diff --git a/etcd-manager/cmd/etcd-manager/main.go b/etcd-manager/cmd/etcd-manager/main.go index 1c7385b60..f97be1bea 100644 --- a/etcd-manager/cmd/etcd-manager/main.go +++ b/etcd-manager/cmd/etcd-manager/main.go @@ -198,7 +198,7 @@ func (o *EtcdManagerOptions) InitDefaults() { o.IPFilter = os.Getenv("ETCD_MANAGER_IP_FILTER") } -func parseIPFilter(o *EtcdManagerOptions) (*net.IPNet, error) { +func parseIPFilter(o *EtcdManagerOptions) ([]*net.IPNet, error) { if o.IPFilter == "" { return nil, nil } @@ -207,8 +207,19 @@ func parseIPFilter(o *EtcdManagerOptions) (*net.IPNet, error) { return nil, fmt.Errorf("is only supported with provider 'openstack'") } - _, parsedIPFilter, err := net.ParseCIDR(o.IPFilter) - return parsedIPFilter, err + var parsedIPFilters []*net.IPNet + + for _, cidr := range strings.Split(o.IPFilter, ",") { + cidr = strings.TrimSpace(cidr) + _, parsedIPFilter, err := net.ParseCIDR(cidr) + if err != nil { + return nil, err + } + + parsedIPFilters = append(parsedIPFilters, parsedIPFilter) + } + + return parsedIPFilters, nil } // RunEtcdManager runs the etcd-manager, returning only we should exit. diff --git a/etcd-manager/cmd/etcd-manager/main_test.go b/etcd-manager/cmd/etcd-manager/main_test.go index 16968326c..cac89ee72 100644 --- a/etcd-manager/cmd/etcd-manager/main_test.go +++ b/etcd-manager/cmd/etcd-manager/main_test.go @@ -63,9 +63,9 @@ func TestParseIPFilterReturnsUnsupportedProviderError(t *testing.T) { } func TestParseIPFilterReturnsErrorOnInvalidCIDR(t *testing.T) { - o := getTestData("192.168.0.0/123", "openstack") + o := getTestData("192.168.0.0/123, 2001:db8::/64", "openstack") - expectedErr := &net.ParseError{Type: "CIDR address", Text: o.IPFilter} + expectedErr := &net.ParseError{Type: "CIDR address", Text: "192.168.0.0/123"} _, actualErr := parseIPFilter(o) @@ -73,19 +73,12 @@ func TestParseIPFilterReturnsErrorOnInvalidCIDR(t *testing.T) { } func TestParseIPFilterReturnsParsedCIDR(t *testing.T) { - o := getTestData("192.168.0.0/16", "openstack") + o := getTestData("192.168.0.0/16, 2001:db8::/64", "openstack") - _, expectedIPFilter, _ := net.ParseCIDR(o.IPFilter) - - actualIPFilter, err := parseIPFilter(o) - - assertTestResults(t, err, expectedIPFilter, actualIPFilter) -} - -func TestParseIPFilterReturnsParsedIPv6CIDR(t *testing.T) { - o := getTestData("2001:db8::/64", "openstack") - - _, expectedIPFilter, _ := net.ParseCIDR(o.IPFilter) + var expectedIPFilter []*net.IPNet + _, cidr1, _ := net.ParseCIDR("192.168.0.0/16") + _, cidr2, _ := net.ParseCIDR("2001:db8::/64") + expectedIPFilter = append(expectedIPFilter, cidr1, cidr2) actualIPFilter, err := parseIPFilter(o) @@ -100,7 +93,7 @@ func TestParseInitDefaultReturnsEmptyStringForIPFilter(t *testing.T) { } func TestParseInitDefaultReturnsValueOfEnvVarForIPFilter(t *testing.T) { - expectedIPFilter := "192.168.0.0/16" + expectedIPFilter := "192.168.0.0/16, 2001:db8::/64" os.Setenv("ETCD_MANAGER_IP_FILTER", expectedIPFilter) var o EtcdManagerOptions diff --git a/etcd-manager/pkg/volumes/openstack/util.go b/etcd-manager/pkg/volumes/openstack/util.go index e6bfd8916..681b141b3 100644 --- a/etcd-manager/pkg/volumes/openstack/util.go +++ b/etcd-manager/pkg/volumes/openstack/util.go @@ -27,7 +27,8 @@ const ( openstackAddress = "addr" ) -func GetServerFixedIP(addrs map[string]interface{}, name string, ipFilter *net.IPNet) (poolAddress string, err error) { +func getAllServerFixedIPs(addrs map[string]interface{}) []string { + var fixedIPs []string for _, address := range addrs { if addresses, ok := address.([]interface{}); ok { for _, addr := range addresses { @@ -35,18 +36,30 @@ func GetServerFixedIP(addrs map[string]interface{}, name string, ipFilter *net.I if addrType, ok := addrMap[openstackExternalIPType]; ok && addrType == openstackAddressFixed { if fixedIP, ok := addrMap[openstackAddress]; ok { if fixedIPStr, ok := fixedIP.(string); ok { - if ipFilter != nil { - if ipFilter.Contains(net.ParseIP(fixedIPStr)) { - return fixedIPStr, nil - } - } else { - return fixedIPStr, nil - } + fixedIPs = append(fixedIPs, fixedIPStr) } } } } } } + return fixedIPs +} + +func GetServerFixedIP(addrs map[string]interface{}, name string, ipFilter []*net.IPNet) (poolAddress string, err error) { + fixedIPs := getAllServerFixedIPs(addrs) + + if ipFilter != nil { + for _, cidr := range ipFilter { + for _, fixedIP := range fixedIPs { + if cidr.Contains(net.ParseIP(fixedIP)) { + return fixedIP, nil + } + } + } + } else if len(fixedIPs) > 0 { + return fixedIPs[0], nil + } + return "", fmt.Errorf("failed to find Fixed IP address for server %s", name) } diff --git a/etcd-manager/pkg/volumes/openstack/util_test.go b/etcd-manager/pkg/volumes/openstack/util_test.go index 2311acf3e..60ebb8fd0 100644 --- a/etcd-manager/pkg/volumes/openstack/util_test.go +++ b/etcd-manager/pkg/volumes/openstack/util_test.go @@ -107,7 +107,10 @@ func TestReturnFirstFixedIP(t *testing.T) { func TestReturnErrorOnNonMatchingCIDR(t *testing.T) { td := getTestData() - _, ipFilter, _ := net.ParseCIDR("172.16.0.0/16") + + var ipFilter []*net.IPNet + _, cidr, _ := net.ParseCIDR("172.16.0.0/16") + ipFilter = append(ipFilter, cidr) expectedErr := fmt.Errorf("failed to find Fixed IP address for server %s", td.clusterName) @@ -118,7 +121,12 @@ func TestReturnErrorOnNonMatchingCIDR(t *testing.T) { func TestReturnFirstIPMatchingCIDR(t *testing.T) { td := getTestData() - _, ipFilter, _ := net.ParseCIDR("192.168.2.0/24") + + var ipFilter []*net.IPNet + _, cidr1, _ := net.ParseCIDR("192.168.2.0/24") + _, cidr2, _ := net.ParseCIDR("2001:db8::/64") + ipFilter = append(ipFilter, cidr1, cidr2) + t.Log(ipFilter) expectedIP := td.ips[3] @@ -129,7 +137,12 @@ func TestReturnFirstIPMatchingCIDR(t *testing.T) { func TestReturnFirstIPv6MatchingCIDR(t *testing.T) { td := getTestData() - _, ipFilter, _ := net.ParseCIDR("2001:db8::/64") + + var ipFilter []*net.IPNet + _, cidr1, _ := net.ParseCIDR("2001:db8::/64") + _, cidr2, _ := net.ParseCIDR("192.168.2.0/24") + ipFilter = append(ipFilter, cidr1, cidr2) + t.Log(ipFilter) expectedIP := td.ips[1] diff --git a/etcd-manager/pkg/volumes/openstack/volumes.go b/etcd-manager/pkg/volumes/openstack/volumes.go index 46dceefbf..30cd8624a 100644 --- a/etcd-manager/pkg/volumes/openstack/volumes.go +++ b/etcd-manager/pkg/volumes/openstack/volumes.go @@ -54,7 +54,7 @@ type OpenstackVolumes struct { matchTagKeys []string matchTags map[string]string - ipFilter *net.IPNet + ipFilter []*net.IPNet computeClient *gophercloud.ServiceClient volumeClient *gophercloud.ServiceClient @@ -70,7 +70,7 @@ type OpenstackVolumes struct { var _ volumes.Volumes = &OpenstackVolumes{} // NewOpenstackVolumes builds a OpenstackVolume -func NewOpenstackVolumes(clusterName string, volumeTags []string, nameTag string, ipFilter *net.IPNet) (*OpenstackVolumes, error) { +func NewOpenstackVolumes(clusterName string, volumeTags []string, nameTag string, ipFilter []*net.IPNet) (*OpenstackVolumes, error) { metadata, err := getLocalMetadata() if err != nil {