diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 536268202c..b27c7601b5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,7 +56,7 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 with: - version: v1.59.1 + version: v1.61.0 skip-go-installation: true args: --timeout=3m - name: golic diff --git a/Makefile b/Makefile index 97b3ece241..3ac70a5e0c 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ LOG_FORMAT ?= simple LOG_LEVEL ?= debug CONTROLLER_GEN_VERSION ?= v0.15.0 GOLIC_VERSION ?= v0.7.2 -GOLANGCI_VERSION ?= v1.60.3 +GOLANGCI_VERSION ?= v1.61.0 POD_NAMESPACE ?= k8gb CLUSTER_GEO_TAG ?= eu EXT_GSLB_CLUSTERS_GEO_TAGS ?= us diff --git a/chart/k8gb/templates/coredns-cm.yaml b/chart/k8gb/templates/coredns-cm.yaml index b1ffcc6caa..b2bfb34df9 100644 --- a/chart/k8gb/templates/coredns-cm.yaml +++ b/chart/k8gb/templates/coredns-cm.yaml @@ -7,7 +7,8 @@ metadata: apiVersion: v1 data: Corefile: |- - {{ .Values.k8gb.dnsZone }}:5353 { +{{- range .Values.k8gb.dnsZones }} + {{ .zone }}:5353 { errors health {{- if .Values.k8gb.coredns.extra_plugins }} @@ -20,10 +21,11 @@ data: forward . /etc/resolv.conf k8s_crd { filter k8gb.absa.oss/dnstype=local - negttl {{ .Values.k8gb.dnsZoneNegTTL }} + negttl {{ .dnsZoneNegTTL | default 30 }} loadbalance weight } } +{{- end }} {{- with .Values.k8gb.coredns.extraServerBlocks -}} {{- tpl . $ | nindent 4 }} {{- end }} diff --git a/chart/k8gb/values.schema.json b/chart/k8gb/values.schema.json index 8eec0b7954..4b6f69cfc2 100644 --- a/chart/k8gb/values.schema.json +++ b/chart/k8gb/values.schema.json @@ -266,17 +266,11 @@ "deployRbac": { "type": "boolean" }, - "dnsZone": { - "format": "idn-hostname", - "minLength": 1 - }, - "dnsZoneNegTTL": { - "type": "integer", - "minimum": 0 - }, - "edgeDNSZone": { - "format": "idn-hostname", - "minLength": 1 + "dnsZones": { + "type": "array", + "items": { + "$ref": "#/definitions/k8gbDnsZone" + } }, "edgeDNSServers": { "type": "array", @@ -330,9 +324,8 @@ "required": [ "clusterGeoTag", "extGslbClustersGeoTags", - "dnsZone", "edgeDNSServers", - "edgeDNSZone" + "dnsZones" ], "title": "k8gb" }, @@ -405,6 +398,28 @@ } } }, + "k8gbDnsZone": { + "type": "object", + "properties": { + "edgeZone": { + "type": "string", + "format": "idn-hostname" + }, + "zone": { + "type": "string", + "format": "idn-hostname" + }, + "dnsZoneNegTTL": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "zone", + "dnsZoneNegTTL", + "edgeZone" + ] + }, "Ns1": { "type": "object", "additionalProperties": false, diff --git a/chart/k8gb/values.yaml b/chart/k8gb/values.yaml index 0ca73d40d3..545436a219 100644 --- a/chart/k8gb/values.yaml +++ b/chart/k8gb/values.yaml @@ -13,12 +13,13 @@ k8gb: deployCrds: true # -- whether it should also deploy the service account, cluster role and cluster role binding deployRbac: true - # -- dnsZone controlled by gslb - dnsZone: "cloud.example.com" - # -- Negative TTL for SOA record - dnsZoneNegTTL: 300 - # -- main zone which would contain gslb zone to delegate - edgeDNSZone: "example.com" # main zone which would contain gslb zone to delegate + dnsZones: + - # -- main zone which would contain gslb zone to delegate + edgeZone: "example.com" + # -- dnsZone controlled by gslb + zone: "cloud.example.com" + # -- Negative TTL for SOA record + dnsZoneNegTTL: 300 # -- host/ip[:port] format is supported here where port defaults to 53 edgeDNSServers: # -- use this DNS server as a main resolver to enable cross k8gb DNS based communication diff --git a/controllers/depresolver/depresolver.go b/controllers/depresolver/depresolver.go index 600cc5cd13..65ec2e16c8 100644 --- a/controllers/depresolver/depresolver.go +++ b/controllers/depresolver/depresolver.go @@ -132,10 +132,14 @@ type Config struct { fallbackEdgeDNSServerName string `env:"EDGE_DNS_SERVER"` // to avoid breaking changes is used as fallback server port for EdgeDNSServers fallbackEdgeDNSServerPort int `env:"EDGE_DNS_SERVER_PORT, default=53"` + // DNSZones + DNSZones utils.DNSZoneList // EdgeDNSZone main zone which would contain gslb zone to delegate; e.g. example.com - EdgeDNSZone string `env:"EDGE_DNS_ZONE"` + // to avoid breaking changes is used as fallback server for DNSZones + fallbackEdgeDNSZone string `env:"EDGE_DNS_ZONE"` // DNSZone controlled by gslb; e.g. cloud.example.com - DNSZone string `env:"DNS_ZONE"` + // to avoid breaking changes is used as fallback server for DNSZones + fallbackDNSZone string `env:"DNS_ZONE"` // K8gbNamespace k8gb namespace K8gbNamespace string `env:"POD_NAMESPACE"` // Infoblox configuration diff --git a/controllers/depresolver/depresolver_config.go b/controllers/depresolver/depresolver_config.go index db15da2f1a..b4c4d20ddb 100644 --- a/controllers/depresolver/depresolver_config.go +++ b/controllers/depresolver/depresolver_config.go @@ -38,8 +38,7 @@ const ( ExtClustersGeoTagsKey = "EXT_GSLB_CLUSTERS_GEO_TAGS" ExtDNSEnabledKey = "EXTDNS_ENABLED" EdgeDNSServersKey = "EDGE_DNS_SERVERS" - EdgeDNSZoneKey = "EDGE_DNS_ZONE" - DNSZoneKey = "DNS_ZONE" + DNSZonesKey = "DNS_ZONES" InfobloxGridHostKey = "INFOBLOX_GRID_HOST" InfobloxVersionKey = "INFOBLOX_WAPI_VERSION" InfobloxPortKey = "INFOBLOX_WAPI_PORT" @@ -67,6 +66,12 @@ const ( // Deprecated: Please use EDGE_DNS_SERVERS instead. EdgeDNSServerPortKey = "EDGE_DNS_SERVER_PORT" + + // Deprecated: Please use DNS_ZONES instead. + EdgeDNSZoneKey = "EDGE_DNS_ZONE" + + // Deprecated: Please use DNS_ZONES instead. + DNSZoneKey = "DNS_ZONE" ) // ResolveOperatorConfig executes once. It reads operator's configuration @@ -87,6 +92,9 @@ func (dr *DependencyResolver) ResolveOperatorConfig() (*Config, error) { fallbackDNS := fmt.Sprintf("%s:%v", dr.config.fallbackEdgeDNSServerName, dr.config.fallbackEdgeDNSServerPort) edgeDNSServerList := env.GetEnvAsArrayOfStringsOrFallback(EdgeDNSServersKey, []string{fallbackDNS}) dr.config.EdgeDNSServers = parseEdgeDNSServers(edgeDNSServerList) + fallbackDNSZone := fmt.Sprintf("%s:%s", dr.config.fallbackEdgeDNSZone, dr.config.fallbackDNSZone) + DNSZoneList := env.GetEnvAsArrayOfStringsOrFallback(DNSZonesKey, []string{fallbackDNSZone}) + dr.config.DNSZones = parseDNSZones(DNSZoneList) dr.config.ExtClustersGeoTags = excludeGeoTag(dr.config.ExtClustersGeoTags, dr.config.ClusterGeoTag) dr.config.Log.Level, _ = zerolog.ParseLevel(strings.ToLower(dr.config.Log.level)) dr.config.Log.Format = parseLogOutputFormat(strings.ToLower(dr.config.Log.format)) @@ -156,11 +164,7 @@ func (dr *DependencyResolver) validateConfig(config *Config, recognizedDNSTypes return fmt.Errorf("error for port of edge dns server(%v): it must be a positive integer between 1 and 65535", s) } } - err = field(EdgeDNSZoneKey, config.EdgeDNSZone).isNotEmpty().matchRegexp(hostNameRegex).err - if err != nil { - return err - } - err = field(DNSZoneKey, config.DNSZone).isNotEmpty().matchRegexp(hostNameRegex).err + err = field(DNSZonesKey, config.DNSZones).isNotEmpty().matchRegexp(dnsZonesRegex).err if err != nil { return err } @@ -181,15 +185,17 @@ func (dr *DependencyResolver) validateConfig(config *Config, recognizedDNSTypes return nil } - serverNames := config.GetExternalClusterNSNames() - serverNames[config.ClusterGeoTag] = config.GetClusterNSName() - for geoTag, nsName := range serverNames { - if len(nsName) > dnsNameMax { - return fmt.Errorf("ns name '%s' exceeds %v charactes limit for [GeoTag: '%s', %s: '%s', %s: '%s']", - nsName, dnsLabelMax, geoTag, EdgeDNSZoneKey, config.EdgeDNSZone, DNSZoneKey, config.DNSZone) - } - if err := validateLabels(nsName); err != nil { - return fmt.Errorf("error for geo tag: %s. %s in ns name %s", geoTag, err, nsName) + for _, zone := range config.DNSZones { + serverNames := config.GetExternalClusterNSNames(zone) + serverNames[config.ClusterGeoTag] = config.GetClusterNSName(zone) + for geoTag, nsName := range serverNames { + if len(nsName) > dnsNameMax { + return fmt.Errorf("ns name '%s' exceeds %v charactes limit for [GeoTag: '%s', %s: '%s']", + nsName, dnsLabelMax, geoTag, DNSZonesKey, zone) + } + if err := validateLabels(nsName); err != nil { + return fmt.Errorf("error for geo tag: %s. %s in ns name %s", geoTag, err, nsName) + } } } @@ -272,6 +278,14 @@ func (dr *DependencyResolver) GetDeprecations() (deprecations []string) { Msg: "Port is an optional item in the comma-separated list of dns edge servers, in following form: dns1:53,dns2 (if not provided after the " + "hostname and colon, it defaults to '53')", }, + EdgeDNSZoneKey: newVar{ + Name: EdgeDNSZoneKey, + Msg: "Pass the DNS zone as comma-separated list in following form: edgezone1:zone1,edgezone2:zone2", + }, + DNSZoneKey: newVar{ + Name: DNSZoneKey, + Msg: "Pass the DNS zone as comma-separated list in following form: edgezone1:zone1,edgezone2:zone2", + }, } for k, v := range deprecated { @@ -279,6 +293,7 @@ func (dr *DependencyResolver) GetDeprecations() (deprecations []string) { deprecations = append(deprecations, fmt.Sprintf("'%s' has been deprecated, use %s instead. Details: %s", k, v.Name, v.Msg)) } } + //nolint:nakedret return } @@ -327,6 +342,28 @@ func parseEdgeDNSServers(serverList []string) (r []utils.DNSServer) { return r } +func parseDNSZones(zones []string) (r []utils.DNSZone) { + r = []utils.DNSZone{} + var edgeZone, zone string + for _, chunk := range zones { + chunk = strings.TrimSpace(chunk) + switch strings.Count(chunk, ":") { + case 1: + chunks := strings.Split(chunk, ":") + edgeZone = chunks[0] + zone = chunks[1] + r = append(r, utils.DNSZone{ + EdgeZone: edgeZone, + Zone: zone, + }) + default: + // not supported + continue + } + } + return r +} + // excludeGeoTag excludes the clusterGeoTag from external geo tags func excludeGeoTag(tags []string, tag string) (r []string) { r = []string{} @@ -366,28 +403,28 @@ func parseLogOutputFormat(value string) LogFormat { return NoFormat } -func (c *Config) GetExternalClusterNSNames() (m map[string]string) { +func (c *Config) GetExternalClusterNSNames(zone utils.DNSZone) (m map[string]string) { m = make(map[string]string, len(c.ExtClustersGeoTags)) for _, tag := range c.ExtClustersGeoTags { - m[tag] = getNsName(tag, c.DNSZone, c.EdgeDNSZone, c.EdgeDNSServers[0].Host) + m[tag] = getNsName(tag, c.EdgeDNSServers[0].Host, zone) } return } -func (c *Config) GetClusterNSName() string { - return getNsName(c.ClusterGeoTag, c.DNSZone, c.EdgeDNSZone, c.EdgeDNSServers[0].Host) +func (c *Config) GetClusterNSName(zone utils.DNSZone) string { + return getNsName(c.ClusterGeoTag, c.EdgeDNSServers[0].Host, zone) } -func (c *Config) GetExternalClusterHeartbeatFQDNs(gslbName string) (m map[string]string) { +func (c *Config) GetExternalClusterHeartbeatFQDNs(gslbName string, zone utils.DNSZone) (m map[string]string) { m = make(map[string]string, len(c.ExtClustersGeoTags)) for _, tag := range c.ExtClustersGeoTags { - m[tag] = getHeartbeatFQDN(gslbName, tag, c.EdgeDNSZone) + m[tag] = getHeartbeatFQDN(gslbName, tag, zone) } return } -func (c *Config) GetClusterHeartbeatFQDN(gslbName string) string { - return getHeartbeatFQDN(gslbName, c.ClusterGeoTag, c.EdgeDNSZone) +func (c *Config) GetClusterHeartbeatFQDN(gslbName string, zone utils.DNSZone) string { + return getHeartbeatFQDN(gslbName, c.ClusterGeoTag, zone) } // getNsName returns NS for geo tag. @@ -398,14 +435,14 @@ func (c *Config) GetClusterHeartbeatFQDN(gslbName string) string { // will generate "gslb-ns-us-k8gb-test-gslb.cloud.example.com" // If edgeDNSServer == localhost or 127.0.0.1 than edgeDNSServer is returned. // The function is private and expects only valid inputs. -func getNsName(tag, dnsZone, edgeDNSZone, edgeDNSServer string) string { +func getNsName(tag, edgeDNSServer string, zone utils.DNSZone) string { if edgeDNSServer == "127.0.0.1" || edgeDNSServer == "localhost" { return edgeDNSServer } const prefix = "gslb-ns" - d := strings.TrimSuffix(dnsZone, "."+edgeDNSZone) + d := strings.TrimSuffix(zone.Zone, "."+zone.EdgeZone) domainX := strings.ReplaceAll(d, ".", "-") - return fmt.Sprintf("%s-%s-%s.%s", prefix, tag, domainX, edgeDNSZone) + return fmt.Sprintf("%s-%s-%s.%s", prefix, tag, domainX, zone.EdgeZone) } // getHeartbeatFQDN returns heartbeat for geo tag. @@ -415,6 +452,6 @@ func getNsName(tag, dnsZone, edgeDNSZone, edgeDNSServer string) string { // gslb.Name: test-gslb-1 // will generate "test-gslb-1-heartbeat-us.cloud.example.com" // The function is private and expects only valid inputs. -func getHeartbeatFQDN(name, geoTag, edgeDNSZone string) string { - return fmt.Sprintf("%s-heartbeat-%s.%s", name, geoTag, edgeDNSZone) +func getHeartbeatFQDN(name, geoTag string, zone utils.DNSZone) string { + return fmt.Sprintf("%s-heartbeat-%s.%s", name, geoTag, zone.EdgeZone) } diff --git a/controllers/depresolver/depresolver_test.go b/controllers/depresolver/depresolver_test.go index 67f15b8b01..e2f588f550 100644 --- a/controllers/depresolver/depresolver_test.go +++ b/controllers/depresolver/depresolver_test.go @@ -66,11 +66,17 @@ var predefinedConfig = Config{ }, fallbackEdgeDNSServerName: "", fallbackEdgeDNSServerPort: 53, - EdgeDNSZone: "example.com", - DNSZone: defaultEdgeDNSZone, - K8gbNamespace: "k8gb", - SplitBrainCheck: true, - MetricsAddress: "0.0.0.0:8080", + DNSZones: []utils2.DNSZone{ + { + EdgeZone: defaultEdgeDNSZone, + Zone: defaultDNSZone, + }, + }, + fallbackEdgeDNSZone: "", + fallbackDNSZone: "", + K8gbNamespace: "k8gb", + SplitBrainCheck: true, + MetricsAddress: "0.0.0.0:8080", Infoblox: Infoblox{ "Infoblox.host.com", "0.0.3", @@ -585,7 +591,7 @@ func TestResolveConfigWithEmptyEdgeDnsZone(t *testing.T) { // arrange defer cleanup() expected := predefinedConfig - expected.EdgeDNSZone = "" + expected.DNSZones = []utils2.DNSZone{} // act,assert arrangeVariablesAndAssert(t, expected, assert.Error) } @@ -594,7 +600,12 @@ func TestResolveConfigWithHostnameEdgeDnsZone(t *testing.T) { // arrange defer cleanup() expected := predefinedConfig - expected.EdgeDNSZone = "company.2l.com" + expected.DNSZones = []utils2.DNSZone{ + { + EdgeZone: "example.com", + Zone: defaultEdgeDNSZone, + }, + } // act,assert arrangeVariablesAndAssert(t, expected, assert.NoError) } @@ -602,19 +613,14 @@ func TestResolveConfigWithHostnameEdgeDnsZone(t *testing.T) { func TestResolveConfigWithInvalidHostnameEdgeDnsZone(t *testing.T) { // arrange defer cleanup() - expected := predefinedConfig - expected.EdgeDNSZone = "https://zone.com" - // act,assert - arrangeVariablesAndAssert(t, expected, assert.Error) -} - -func TestResolveConfigWithInvalidHostnameDnsZone(t *testing.T) { - // arrange - defer cleanup() - expected := predefinedConfig - expected.DNSZone = "dns-zo?ne" - // act,assert - arrangeVariablesAndAssert(t, expected, assert.Error) + configureEnvVar(predefinedConfig) + _ = os.Setenv(DNSZonesKey, "bad//zone:shouldn't-work") + resolver := NewDependencyResolver() + // act + _, err := resolver.ResolveOperatorConfig() + // assert + assert.Error(t, err) + assert.Contains(t, err.Error(), "does not match given criteria") } func TestResolveConfigWithInvalidK8gbNamespace(t *testing.T) { @@ -643,7 +649,7 @@ func TestResolveEmptyExtGeoTags(t *testing.T) { // arrange defer cleanup() expected := predefinedConfig - expected.DNSZone = "" + expected.DNSZones = []utils2.DNSZone{} // act,assert arrangeVariablesAndAssert(t, expected, assert.Error, DNSZoneKey) } @@ -1179,8 +1185,6 @@ func TestHeartBeatWithMultipleExtClusterGeoTag(t *testing.T) { // arrange defer cleanup() customConfig := predefinedConfig - customConfig.DNSZone = defaultDNSZone - customConfig.EdgeDNSZone = defaultEdgeDNSZone customConfig.ClusterGeoTag = defaultClusterGeoTagUs1 customConfig.ExtClustersGeoTags = []string{defaultClusterGeoTagUs2, defaultClusterGeoTagEu} configureEnvVar(customConfig) @@ -1191,12 +1195,13 @@ func TestHeartBeatWithMultipleExtClusterGeoTag(t *testing.T) { // assert assert.NoError(t, err) - assert.Len(t, config.GetExternalClusterHeartbeatFQDNs(geoTag), 2) - assert.Equal(t, "test-gslb-1-heartbeat-us-west-1.cloud.example.com", config.GetClusterHeartbeatFQDN(geoTag)) + zone := customConfig.DNSZones[0] + assert.Len(t, config.GetExternalClusterHeartbeatFQDNs(geoTag, zone), 2) + assert.Equal(t, "test-gslb-1-heartbeat-us-west-1.cloud.example.com", config.GetClusterHeartbeatFQDN(geoTag, zone)) for k, v := range map[string]string{defaultClusterGeoTagUs2: "test-gslb-1-heartbeat-us-east-1.cloud.example.com", defaultClusterGeoTagEu: "test-gslb-1-heartbeat-eu-central-1.cloud.example.com"} { - assert.Equal(t, config.GetExternalClusterHeartbeatFQDNs(geoTag)[k], v) + assert.Equal(t, config.GetExternalClusterHeartbeatFQDNs(geoTag, zone)[k], v) } } @@ -1205,8 +1210,6 @@ func TestHeartBeatWithOneExtClusterGeoTag(t *testing.T) { // arrange defer cleanup() customConfig := predefinedConfig - customConfig.DNSZone = defaultDNSZone - customConfig.EdgeDNSZone = defaultEdgeDNSZone customConfig.ClusterGeoTag = defaultClusterGeoTagUs1 customConfig.ExtClustersGeoTags = []string{defaultClusterGeoTagUs2} configureEnvVar(customConfig) @@ -1217,17 +1220,16 @@ func TestHeartBeatWithOneExtClusterGeoTag(t *testing.T) { // assert assert.NoError(t, err) - assert.Len(t, config.GetExternalClusterHeartbeatFQDNs(geoTag), 1) - assert.Equal(t, "test-gslb-1-heartbeat-us-west-1.cloud.example.com", config.GetClusterHeartbeatFQDN(geoTag)) - assert.Equal(t, config.GetExternalClusterHeartbeatFQDNs(geoTag)[defaultClusterGeoTagUs2], "test-gslb-1-heartbeat-us-east-1.cloud.example.com") + zone := customConfig.DNSZones[0] + assert.Len(t, config.GetExternalClusterHeartbeatFQDNs(geoTag, zone), 1) + assert.Equal(t, "test-gslb-1-heartbeat-us-west-1.cloud.example.com", config.GetClusterHeartbeatFQDN(geoTag, zone)) + assert.Equal(t, config.GetExternalClusterHeartbeatFQDNs(geoTag, zone)[defaultClusterGeoTagUs2], "test-gslb-1-heartbeat-us-east-1.cloud.example.com") } func TestNsServerNamesWithMultipleExtClusterGeoTag(t *testing.T) { // arrange defer cleanup() customConfig := predefinedConfig - customConfig.DNSZone = defaultDNSZone - customConfig.EdgeDNSZone = defaultEdgeDNSZone customConfig.ClusterGeoTag = defaultClusterGeoTagUs1 customConfig.ExtClustersGeoTags = []string{defaultClusterGeoTagUs2, defaultClusterGeoTagEu} configureEnvVar(customConfig) @@ -1238,11 +1240,12 @@ func TestNsServerNamesWithMultipleExtClusterGeoTag(t *testing.T) { // assert assert.NoError(t, err) - assert.Len(t, config.GetExternalClusterNSNames(), 2) - assert.Equal(t, "gslb-ns-us-west-1-k8gb-test-preprod-gslb.cloud.example.com", config.GetClusterNSName()) + zone := customConfig.DNSZones[0] + assert.Len(t, config.GetExternalClusterNSNames(zone), 2) + assert.Equal(t, "gslb-ns-us-west-1-k8gb-test-preprod-gslb.cloud.example.com", config.GetClusterNSName(zone)) for k, v := range map[string]string{defaultClusterGeoTagUs2: "gslb-ns-us-east-1-k8gb-test-preprod-gslb.cloud.example.com", defaultClusterGeoTagEu: "gslb-ns-eu-central-1-k8gb-test-preprod-gslb.cloud.example.com"} { - assert.Equal(t, config.GetExternalClusterNSNames()[k], v) + assert.Equal(t, config.GetExternalClusterNSNames(zone)[k], v) } } @@ -1263,8 +1266,9 @@ func TestNsServerNamesForLocalEdgeDNS(t *testing.T) { config, err := resolver.ResolveOperatorConfig() // assert assert.NoError(t, err) - assert.Equal(t, config.GetClusterNSName(), edgeDNSServer) - assert.True(t, reflect.DeepEqual(config.GetExternalClusterNSNames(), map[string]string{"za": edgeDNSServer, "eu": edgeDNSServer})) + zone := customConfig.DNSZones[0] + assert.Equal(t, config.GetClusterNSName(zone), edgeDNSServer) + assert.True(t, reflect.DeepEqual(config.GetExternalClusterNSNames(zone), map[string]string{"za": edgeDNSServer, "eu": edgeDNSServer})) } } @@ -1272,8 +1276,6 @@ func TestNsServerNamesWithOneExtClusterGeoTag(t *testing.T) { // arrange defer cleanup() customConfig := predefinedConfig - customConfig.DNSZone = defaultDNSZone - customConfig.EdgeDNSZone = defaultEdgeDNSZone customConfig.ClusterGeoTag = defaultClusterGeoTagUs1 customConfig.ExtClustersGeoTags = []string{"location-2"} configureEnvVar(customConfig) @@ -1284,17 +1286,16 @@ func TestNsServerNamesWithOneExtClusterGeoTag(t *testing.T) { // assert assert.NoError(t, err) - assert.Len(t, config.GetExternalClusterNSNames(), 1) - assert.Equal(t, "gslb-ns-us-west-1-k8gb-test-preprod-gslb.cloud.example.com", config.GetClusterNSName()) - assert.Equal(t, config.GetExternalClusterNSNames()["location-2"], "gslb-ns-location-2-k8gb-test-preprod-gslb.cloud.example.com") + zone := customConfig.DNSZones[0] + assert.Len(t, config.GetExternalClusterNSNames(zone), 1) + assert.Equal(t, "gslb-ns-us-west-1-k8gb-test-preprod-gslb.cloud.example.com", config.GetClusterNSName(zone)) + assert.Equal(t, config.GetExternalClusterNSNames(zone)["location-2"], "gslb-ns-location-2-k8gb-test-preprod-gslb.cloud.example.com") } func TestNsServerNamesWithExtClusterGeoTagsContainingClusterGeoTag(t *testing.T) { // arrange defer cleanup() customConfig := predefinedConfig - customConfig.DNSZone = defaultDNSZone - customConfig.EdgeDNSZone = defaultEdgeDNSZone customConfig.ClusterGeoTag = defaultClusterGeoTagUs1 customConfig.ExtClustersGeoTags = []string{"location-2", defaultClusterGeoTagUs1} configureEnvVar(customConfig) @@ -1305,17 +1306,22 @@ func TestNsServerNamesWithExtClusterGeoTagsContainingClusterGeoTag(t *testing.T) // assert assert.NoError(t, err) - assert.Len(t, config.GetExternalClusterNSNames(), 1) - assert.Equal(t, "gslb-ns-us-west-1-k8gb-test-preprod-gslb.cloud.example.com", config.GetClusterNSName()) - assert.Equal(t, config.GetExternalClusterNSNames()["location-2"], "gslb-ns-location-2-k8gb-test-preprod-gslb.cloud.example.com") + zone := customConfig.DNSZones[0] + assert.Len(t, config.GetExternalClusterNSNames(zone), 1) + assert.Equal(t, "gslb-ns-us-west-1-k8gb-test-preprod-gslb.cloud.example.com", config.GetClusterNSName(zone)) + assert.Equal(t, config.GetExternalClusterNSNames(zone)["location-2"], "gslb-ns-location-2-k8gb-test-preprod-gslb.cloud.example.com") } func TestNsServerNamesLargeDNSZone(t *testing.T) { defer cleanup() // arrange DNSZone exceeds customConfig := predefinedConfig - customConfig.DNSZone = "k8gb-test-preprod-lorem-ipsum-donor-blah-blah-blah.gslb.cloud.example.com" - customConfig.EdgeDNSZone = defaultEdgeDNSZone + customConfig.DNSZones = []utils2.DNSZone{ + { + Zone: "k8gb-test-preprod-lorem-ipsum-donor-blah-blah-blah.gslb.cloud.example.com", + EdgeZone: defaultEdgeDNSZone, + }, + } customConfig.ClusterGeoTag = "us" configureEnvVar(customConfig) resolver := NewDependencyResolver() @@ -1325,8 +1331,9 @@ func TestNsServerNamesLargeDNSZone(t *testing.T) { // assert assert.Error(t, err) - assert.Equal(t, "gslb-ns-us-k8gb-test-preprod-lorem-ipsum-donor-blah-blah-blah-gslb.cloud.example.com", config.GetClusterNSName()) - extNsNames := config.GetExternalClusterNSNames() + zone := customConfig.DNSZones[0] + assert.Equal(t, "gslb-ns-us-k8gb-test-preprod-lorem-ipsum-donor-blah-blah-blah-gslb.cloud.example.com", config.GetClusterNSName(zone)) + extNsNames := config.GetExternalClusterNSNames(zone) expectedExtNsNames := map[string]string{"za": "gslb-ns-za-k8gb-test-preprod-lorem-ipsum-donor-blah-blah-blah-gslb.cloud.example.com", "eu": "gslb-ns-eu-k8gb-test-preprod-lorem-ipsum-donor-blah-blah-blah-gslb.cloud.example.com"} assert.True(t, reflect.DeepEqual(extNsNames, expectedExtNsNames), "maps must be equal: \n %v\n %v", extNsNames, expectedExtNsNames) @@ -1337,8 +1344,6 @@ func TestNsServerNamesWithLargeExtClusterGeoTag(t *testing.T) { defer cleanup() // arrange customConfig := predefinedConfig - customConfig.DNSZone = defaultDNSZone - customConfig.EdgeDNSZone = defaultEdgeDNSZone customConfig.ClusterGeoTag = "us" customConfig.ExtClustersGeoTags = []string{} customConfig.ExtClustersGeoTags = append(customConfig.ExtClustersGeoTags, predefinedConfig.ExtClustersGeoTags...) @@ -1351,8 +1356,9 @@ func TestNsServerNamesWithLargeExtClusterGeoTag(t *testing.T) { // assert assert.Error(t, err) - assert.Equal(t, "gslb-ns-us-k8gb-test-preprod-gslb.cloud.example.com", config.GetClusterNSName()) - extNsNames := config.GetExternalClusterNSNames() + zone := customConfig.DNSZones[0] + assert.Equal(t, "gslb-ns-us-k8gb-test-preprod-gslb.cloud.example.com", config.GetClusterNSName(zone)) + extNsNames := config.GetExternalClusterNSNames(zone) expectedExtNsNames := map[string]string{largeGeoTag: "gslb-ns-za-lorem-ipsum-donor-b-blah-lorem-k8gb-test-preprod-gslb.cloud.example.com", "eu": "gslb-ns-eu-k8gb-test-preprod-gslb.cloud.example.com"} assert.True(t, reflect.DeepEqual(extNsNames, expectedExtNsNames), "maps must be equal: \n %v\n %v", extNsNames, expectedExtNsNames) @@ -1363,8 +1369,6 @@ func TestNsServerNamesWithLargeClusterGeoTag(t *testing.T) { defer cleanup() // arrange customConfig := predefinedConfig - customConfig.DNSZone = defaultDNSZone - customConfig.EdgeDNSZone = defaultEdgeDNSZone customConfig.ClusterGeoTag = "us-lorem-ipsum-donor-blah-blah-blah-blah" configureEnvVar(customConfig) resolver := NewDependencyResolver() @@ -1374,31 +1378,37 @@ func TestNsServerNamesWithLargeClusterGeoTag(t *testing.T) { // assert assert.Error(t, err) - assert.Equal(t, "gslb-ns-us-lorem-ipsum-donor-blah-blah-blah-blah-k8gb-test-preprod-gslb.cloud.example.com", config.GetClusterNSName()) - extNsNames := config.GetExternalClusterNSNames() + zone := customConfig.DNSZones[0] + assert.Equal(t, "gslb-ns-us-lorem-ipsum-donor-blah-blah-blah-blah-k8gb-test-preprod-gslb.cloud.example.com", config.GetClusterNSName(zone)) + extNsNames := config.GetExternalClusterNSNames(zone) expectedExtNsNames := map[string]string{"za": "gslb-ns-za-k8gb-test-preprod-gslb.cloud.example.com", "eu": "gslb-ns-eu-k8gb-test-preprod-gslb.cloud.example.com"} assert.True(t, reflect.DeepEqual(extNsNames, expectedExtNsNames), "maps must be equal: \n %v\n %v", extNsNames, expectedExtNsNames) - } func TestNsServerNamesWithExceededDNSNameSize(t *testing.T) { // arrange defer cleanup() customConfig := predefinedConfig - customConfig.EdgeDNSZone = "seo.cloud.example01.lorem.ipsum.alfa.bravo.charlie.delta.echo.foxtrot.golf.hotel.india." + + edgeZone := "seo.cloud.example01.lorem.ipsum.alfa.bravo.charlie.delta.echo.foxtrot.golf.hotel.india." + "juliett.kilo.lima.mike.november.oscar.papa.quebec.romeo.sierra.tango.uniform.victor.whiskey.x-ray.yenkee.zulu." + "zero.cloud.example.com" - customConfig.DNSZone = "k8gb-test-preprod.gslb." + customConfig.EdgeDNSZone + customConfig.DNSZones = []utils2.DNSZone{ + { + EdgeZone: edgeZone, + Zone: "k8gb-test-preprod.gslb." + edgeZone, + }, + } configureEnvVar(customConfig) resolver := NewDependencyResolver() // act config, err := resolver.ResolveOperatorConfig() // assert assert.NoError(t, err) - assert.Len(t, config.GetClusterNSName(), 253) - assert.Len(t, config.GetExternalClusterNSNames()[customConfig.ExtClustersGeoTags[0]], 253) - assert.Len(t, config.GetExternalClusterNSNames()[customConfig.ExtClustersGeoTags[1]], 253) + zone := customConfig.DNSZones[0] + assert.Len(t, config.GetClusterNSName(zone), 253) + assert.Len(t, config.GetExternalClusterNSNames(zone)[customConfig.ExtClustersGeoTags[0]], 253) + assert.Len(t, config.GetExternalClusterNSNames(zone)[customConfig.ExtClustersGeoTags[1]], 253) // arrange // extend cluster geo tag with one character so NsServerName exceeds length limit @@ -1409,9 +1419,9 @@ func TestNsServerNamesWithExceededDNSNameSize(t *testing.T) { config, err = resolver.ResolveOperatorConfig() // assert assert.Error(t, err) - assert.Len(t, config.GetClusterNSName(), 254) - assert.Len(t, config.GetExternalClusterNSNames()[customConfig.ExtClustersGeoTags[0]], 253) - assert.Len(t, config.GetExternalClusterNSNames()[customConfig.ExtClustersGeoTags[1]], 253) + assert.Len(t, config.GetClusterNSName(zone), 254) + assert.Len(t, config.GetExternalClusterNSNames(zone)[customConfig.ExtClustersGeoTags[0]], 253) + assert.Len(t, config.GetExternalClusterNSNames(zone)[customConfig.ExtClustersGeoTags[1]], 253) } func TestMetricsAddressIsValid(t *testing.T) { @@ -1504,7 +1514,7 @@ func arrangeVariablesAndAssert(t *testing.T, expected Config, } func cleanup() { - for _, s := range []string{ReconcileRequeueSecondsKey, ClusterGeoTagKey, ExtClustersGeoTagsKey, EdgeDNSZoneKey, DNSZoneKey, EdgeDNSServersKey, + for _, s := range []string{ReconcileRequeueSecondsKey, ClusterGeoTagKey, ExtClustersGeoTagsKey, DNSZonesKey, EdgeDNSServersKey, ExtDNSEnabledKey, InfobloxGridHostKey, InfobloxVersionKey, InfobloxPortKey, InfobloxUsernameKey, InfobloxPasswordKey, K8gbNamespaceKey, CoreDNSExposedKey, InfobloxHTTPRequestTimeoutKey, InfobloxHTTPPoolConnectionsKey, LogLevelKey, LogFormatKey, LogNoColorKey, MetricsAddressKey, SplitBrainCheckKey, TracingEnabled, @@ -1518,12 +1528,13 @@ func cleanup() { func configureEnvVar(config Config) { _ = os.Unsetenv(EdgeDNSServerKey) _ = os.Unsetenv(EdgeDNSServerPortKey) + _ = os.Unsetenv(EdgeDNSZoneKey) + _ = os.Unsetenv(DNSZoneKey) _ = os.Setenv(ReconcileRequeueSecondsKey, strconv.Itoa(config.ReconcileRequeueSeconds)) _ = os.Setenv(ClusterGeoTagKey, config.ClusterGeoTag) _ = os.Setenv(ExtClustersGeoTagsKey, strings.Join(config.ExtClustersGeoTags, ",")) _ = os.Setenv(EdgeDNSServersKey, config.EdgeDNSServers.String()) - _ = os.Setenv(EdgeDNSZoneKey, config.EdgeDNSZone) - _ = os.Setenv(DNSZoneKey, config.DNSZone) + _ = os.Setenv(DNSZonesKey, config.DNSZones.String()) _ = os.Setenv(K8gbNamespaceKey, config.K8gbNamespace) _ = os.Setenv(ExtDNSEnabledKey, strconv.FormatBool(config.extDNSEnabled)) _ = os.Setenv(CoreDNSExposedKey, strconv.FormatBool(config.CoreDNSExposed)) diff --git a/controllers/depresolver/depresolver_validator.go b/controllers/depresolver/depresolver_validator.go index 87222e08b3..192f203245 100644 --- a/controllers/depresolver/depresolver_validator.go +++ b/controllers/depresolver/depresolver_validator.go @@ -36,6 +36,7 @@ const ( hostNamesWithPortsRegex1 = "^(" + hostNamePart + "(:\\d{1,5})?(\\s*,\\s*)?)+$" // doesn't end with comma or space (golang doesn't support negative lookbehind regexps) hostNamesWithPortsRegex2 = "^.*[^,]$" + dnsZonesRegex = "^(" + hostNamePart + ":[^,]+)(,(" + hostNamePart + ":[^,]+))*?$" // ipAddressRegex matches valid IPv4 addresses ipAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$" // versionNumberRegex matches version in formats 0.1.2, v0.1.2, v0.1.2-alpha @@ -74,6 +75,8 @@ func field(name string, value interface{}) *validator { validator.strArr = v case utils.DNSList: validator.strValue = v.String() + case utils.DNSZoneList: + validator.strValue = v.String() default: // float32, float64, bool, interface{}, maps, slices, Custom Types validator.err = fmt.Errorf("can't parse '%v' of type '%T' as int or string", v, v) diff --git a/controllers/dnsupdate.go b/controllers/dnsupdate.go index df9181f9da..bdc02db864 100644 --- a/controllers/dnsupdate.go +++ b/controllers/dnsupdate.go @@ -25,6 +25,7 @@ import ( "github.com/k8gb-io/k8gb/controllers/depresolver" "github.com/k8gb-io/k8gb/controllers/providers/assistant" + "github.com/k8gb-io/k8gb/controllers/utils" k8gbv1beta1 "github.com/k8gb-io/k8gb/api/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -32,7 +33,7 @@ import ( externaldns "sigs.k8s.io/external-dns/endpoint" ) -func (r *GslbReconciler) gslbDNSEndpoint(gslb *k8gbv1beta1.Gslb) (*externaldns.DNSEndpoint, error) { +func (r *GslbReconciler) gslbDNSEndpoint(gslb *k8gbv1beta1.Gslb, zone utils.DNSZone) (*externaldns.DNSEndpoint, error) { _, s := r.Tracer.Start(context.Background(), "gslbDNSEndpoint") defer s.End() var gslbHosts []*externaldns.Endpoint @@ -48,8 +49,8 @@ func (r *GslbReconciler) gslbDNSEndpoint(gslb *k8gbv1beta1.Gslb) (*externaldns.D for host, health := range serviceHealth { var finalTargets = assistant.NewTargets() - if !strings.Contains(host, r.Config.EdgeDNSZone) { - return nil, fmt.Errorf("ingress host %s does not match delegated zone %s", host, r.Config.EdgeDNSZone) + if !strings.Contains(host, zone.EdgeZone) { + return nil, fmt.Errorf("ingress host %s does not match delegated zone %s", host, zone.EdgeZone) } isPrimary := gslb.Spec.Strategy.PrimaryGeoTag == r.Config.ClusterGeoTag @@ -68,7 +69,7 @@ func (r *GslbReconciler) gslbDNSEndpoint(gslb *k8gbv1beta1.Gslb) (*externaldns.D } // Check if host is alive on external Gslb - externalTargets := r.DNSProvider.GetExternalTargets(host) + externalTargets := r.DNSProvider.GetExternalTargets(host, zone) externalTargets.Sort() if len(externalTargets) > 0 { diff --git a/controllers/finalize.go b/controllers/finalize.go index 2ecff0331c..ee4f5c73d8 100644 --- a/controllers/finalize.go +++ b/controllers/finalize.go @@ -22,13 +22,14 @@ import ( "context" k8gbv1beta1 "github.com/k8gb-io/k8gb/api/v1beta1" + "github.com/k8gb-io/k8gb/controllers/utils" ) -func (r *GslbReconciler) finalizeGslb(gslb *k8gbv1beta1.Gslb) (err error) { +func (r *GslbReconciler) finalizeGslb(gslb *k8gbv1beta1.Gslb, zone utils.DNSZone) (err error) { // needs to do before the CR can be deleted. Examples // of finalizers include performing backups and deleting // resources that are not owned by this CR, like a PVC. - err = r.DNSProvider.Finalize(gslb) + err = r.DNSProvider.Finalize(gslb, zone) if err != nil { log.Err(err). Str("gslb", gslb.Name). diff --git a/controllers/gslb_controller_reconciliation.go b/controllers/gslb_controller_reconciliation.go index c626d74e0b..2dc241885a 100644 --- a/controllers/gslb_controller_reconciliation.go +++ b/controllers/gslb_controller_reconciliation.go @@ -22,6 +22,7 @@ import ( "context" "fmt" "reflect" + "strings" "github.com/k8gb-io/k8gb/controllers/utils" @@ -103,42 +104,6 @@ func (r *GslbReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. Str("namespace", gslb.Namespace). Interface("strategy", gslb.Spec.Strategy). Msg("Resolved strategy") - // == Finalizer business == - - // Check if the Gslb instance is marked to be deleted, which is - // indicated by the deletion timestamp being set. - isGslbMarkedToBeDeleted := gslb.GetDeletionTimestamp() != nil - if isGslbMarkedToBeDeleted { - // For the legacy reasons, delete all finalizers that corresponds with the slice - // see: https://sdk.operatorframework.io/docs/upgrading-sdk-version/v1.4.0/#change-your-operators-finalizer-names - _, fSpan := r.Tracer.Start(ctx, "finalize") - for _, f := range []string{gslbFinalizer, "finalizer.k8gb.absa.oss"} { - if contains(gslb.GetFinalizers(), f) { - // Run finalization logic for gslbFinalizer. If the - // finalization logic fails, don't remove the finalizer so - // that we can retry during the next reconciliation. - if err := r.finalizeGslb(gslb); err != nil { - fSpan.RecordError(err) - fSpan.SetStatus(codes.Error, err.Error()) - return result.RequeueError(err) - } - - // Remove gslbFinalizer. Once all finalizers have been - // removed, the object will be deleted. - gslb.SetFinalizers(remove(gslb.GetFinalizers(), f)) - err := r.Update(ctx, gslb) - if err != nil { - fSpan.RecordError(err) - fSpan.SetStatus(codes.Error, err.Error()) - return result.RequeueError(err) - } - } - - } - fSpan.End() - log.Info().Msg("reconciler exit") - return result.Stop() - } // Add finalizer for this CR if !contains(gslb.GetFinalizers(), gslbFinalizer) { @@ -176,7 +141,74 @@ func (r *GslbReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. m.IncrementError(gslb) return result.RequeueError(fmt.Errorf("getting GSLB servers (%s)", err)) } - gslb.Status.Servers = servers + + var zone utils.DNSZone + var matchedServers []*k8gbv1beta1.Server + for _, server := range servers { + log.Debug(). + Str("server", server.Host). + Msg("Checking server") + for _, z := range r.Config.DNSZones { + log.Debug(). + Str("zone", z.Zone). + Msg("Checking zone") + if strings.HasSuffix(server.Host, z.Zone) { + log.Debug(). + Str("server", server.Host). + Str("zone", z.Zone). + Msg("Matched zone to server host") + zone = z + matchedServers = append(matchedServers, server) + } + } + } + + if zone == (utils.DNSZone{}) { + log.Error(). + Str("zones", r.Config.DNSZones.String()). + Msg("No configured zones match Gslb hosts") + m.IncrementError(gslb) + return result.Requeue() + } + + // these are the matched servers for the Ingress of the service being Gslb'd + gslb.Status.Servers = matchedServers + + // == Finalizer business == + // Check if the Gslb instance is marked to be deleted, which is + // indicated by the deletion timestamp being set. + isGslbMarkedToBeDeleted := gslb.GetDeletionTimestamp() != nil + if isGslbMarkedToBeDeleted { + // For the legacy reasons, delete all finalizers that corresponds with the slice + // see: https://sdk.operatorframework.io/docs/upgrading-sdk-version/v1.4.0/#change-your-operators-finalizer-names + _, fSpan := r.Tracer.Start(ctx, "finalize") + for _, f := range []string{gslbFinalizer, "finalizer.k8gb.absa.oss"} { + if contains(gslb.GetFinalizers(), f) { + // Run finalization logic for gslbFinalizer. If the + // finalization logic fails, don't remove the finalizer so + // that we can retry during the next reconciliation. + if err := r.finalizeGslb(gslb, zone); err != nil { + fSpan.RecordError(err) + fSpan.SetStatus(codes.Error, err.Error()) + return result.RequeueError(err) + } + + // Remove gslbFinalizer. Once all finalizers have been + // removed, the object will be deleted. + gslb.SetFinalizers(remove(gslb.GetFinalizers(), f)) + err := r.Update(ctx, gslb) + if err != nil { + fSpan.RecordError(err) + fSpan.SetStatus(codes.Error, err.Error()) + return result.RequeueError(err) + } + } + + } + fSpan.End() + log.Info().Msg("reconciler exit") + return result.Stop() + } loadBalancerExposedIPs, err := refResolver.GetGslbExposedIPs(r.Config.EdgeDNSServers) if err != nil { @@ -190,7 +222,7 @@ func (r *GslbReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. Msg("Resolved LoadBalancer and Server configuration referenced by Ingress") // == external-dns dnsendpoints CRs == - dnsEndpoint, err := r.gslbDNSEndpoint(gslb) + dnsEndpoint, err := r.gslbDNSEndpoint(gslb, zone) if err != nil { m.IncrementError(gslb) return result.RequeueError(err) @@ -206,7 +238,7 @@ func (r *GslbReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl. // == handle delegated zone in Edge DNS _, szd := r.Tracer.Start(ctx, "CreateZoneDelegationForExternalDNS") - err = r.DNSProvider.CreateZoneDelegationForExternalDNS(gslb) + err = r.DNSProvider.CreateZoneDelegationForExternalDNS(gslb, zone) if err != nil { log.Err(err).Msg("Unable to create zone delegation") m.IncrementError(gslb) diff --git a/controllers/gslb_controller_reconciliation_test.go b/controllers/gslb_controller_reconciliation_test.go index 7ba90e4d3c..eb58a265ee 100644 --- a/controllers/gslb_controller_reconciliation_test.go +++ b/controllers/gslb_controller_reconciliation_test.go @@ -83,8 +83,12 @@ var predefinedConfig = depresolver.Config{ Port: 7753, }, }, - EdgeDNSZone: "example.com", - DNSZone: "cloud.example.com", + DNSZones: []utils.DNSZone{ + { + EdgeZone: "example.com", + Zone: "cloud.example.com", + }, + }, K8gbNamespace: "k8gb", Infoblox: depresolver.Infoblox{ Host: "fakeinfoblox.example.com", @@ -394,14 +398,14 @@ func TestGslbErrorsIncrement(t *testing.T) { m := mocks.NewMockProvider(ctrl) cnt := testutil.ToFloat64(metrics.Metrics().Get(metrics.K8gbGslbErrorsTotal).AsCounterVec().With(label)) m.EXPECT().SaveDNSEndpoint(gomock.Any(), gomock.Any()).Return(fmt.Errorf("save DNS error")).Times(1) - m.EXPECT().GetExternalTargets(gomock.Any()).Return(assistant.Targets{}).AnyTimes() + m.EXPECT().GetExternalTargets(gomock.Any(), gomock.Any()).Return(assistant.Targets{}).AnyTimes() settings.reconciler.DNSProvider = m // act _, err := settings.reconciler.Reconcile(context.TODO(), settings.request) require.Error(t, err) // let's break it on different place m.EXPECT().SaveDNSEndpoint(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - m.EXPECT().CreateZoneDelegationForExternalDNS(gomock.Any()).Return(fmt.Errorf("zone delegation error")).AnyTimes() + m.EXPECT().CreateZoneDelegationForExternalDNS(gomock.Any(), gomock.Any()).Return(fmt.Errorf("zone delegation error")).AnyTimes() _, err = settings.reconciler.Reconcile(context.TODO(), settings.request) cnt2 := testutil.ToFloat64(metrics.Metrics().Get(metrics.K8gbGslbErrorsTotal).AsCounterVec().With(label)) // assert @@ -880,8 +884,7 @@ func TestDetectsIngressHostnameMismatch(t *testing.T) { // getting Gslb and Reconciler predefinedSettings := provideSettings(t, predefinedConfig) customConfig := predefinedConfig - customConfig.EdgeDNSZone = "otherdnszone.com" - predefinedSettings.config = customConfig + customConfig.DNSZones = []utils.DNSZone{{EdgeZone: "otherdnszone.com"}} req := reconcile.Request{ NamespacedName: types.NamespacedName{ Name: predefinedSettings.gslb.Name, @@ -953,7 +956,7 @@ func TestCreatesDNSNSRecordsForExtDNS(t *testing.T) { customConfig.EdgeDNSType = depresolver.DNSTypeExternal customConfig.ClusterGeoTag = "eu" customConfig.ExtClustersGeoTags = []string{"za", "us"} - customConfig.DNSZone = dnsZone + customConfig.DNSZones[0].Zone = dnsZone // apply new environment variables and update config only settings.reconciler.Config = &customConfig // If config is changed, new Route53 provider needs to be re-created. There is no way and reason to change provider @@ -1029,7 +1032,7 @@ func TestCreatesDNSNSRecordsForLoadBalancer(t *testing.T) { customConfig.EdgeDNSType = depresolver.DNSTypeExternal customConfig.ClusterGeoTag = "eu" customConfig.ExtClustersGeoTags = []string{"za", "us"} - customConfig.DNSZone = dnsZone + customConfig.DNSZones[0].Zone = dnsZone // apply new environment variables and update config only settings.reconciler.Config = &customConfig // If config is changed, new Route53 provider needs to be re-created. There is no way and reason to change provider diff --git a/controllers/gslb_controller_weight_test.go b/controllers/gslb_controller_weight_test.go index d496e9a2a8..4c4ad7def5 100644 --- a/controllers/gslb_controller_weight_test.go +++ b/controllers/gslb_controller_weight_test.go @@ -173,16 +173,16 @@ func TestWeight(t *testing.T) { m := mocks.NewMockProvider(ctrl) r := mocks.NewMockGslbResolver(ctrl) m.EXPECT().SaveDNSEndpoint(gomock.Any(), gomock.Any()).Do(assertAnnotation).Return(fmt.Errorf("save DNS error")).Times(1) - m.EXPECT().CreateZoneDelegationForExternalDNS(gomock.Any()).Return(nil).AnyTimes() + m.EXPECT().CreateZoneDelegationForExternalDNS(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() r.EXPECT().ResolveGslbSpec(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(injectWeight).AnyTimes() ts := assistant.Targets{} for k, w := range test.data { ts[k] = &assistant.Target{IPs: w.targets} } - m.EXPECT().GetExternalTargets("roundrobin.cloud.example.com").Return(ts).Times(1) - m.EXPECT().GetExternalTargets("notfound.cloud.example.com").Return(assistant.Targets{}).Times(1) - m.EXPECT().GetExternalTargets("unhealthy.cloud.example.com").Return(assistant.Targets{}).Times(1) + m.EXPECT().GetExternalTargets("roundrobin.cloud.example.com", gomock.Any()).Return(ts).Times(1) + m.EXPECT().GetExternalTargets("notfound.cloud.example.com", gomock.Any()).Return(assistant.Targets{}).Times(1) + m.EXPECT().GetExternalTargets("unhealthy.cloud.example.com", gomock.Any()).Return(assistant.Targets{}).Times(1) settings := provideSettings(t, predefinedConfig) settings.reconciler.DNSProvider = m diff --git a/controllers/mocks/provider_mock.go b/controllers/mocks/provider_mock.go index 71f074a1be..a7a6698c85 100644 --- a/controllers/mocks/provider_mock.go +++ b/controllers/mocks/provider_mock.go @@ -32,6 +32,7 @@ import ( v1beta1 "github.com/k8gb-io/k8gb/api/v1beta1" assistant "github.com/k8gb-io/k8gb/controllers/providers/assistant" + utils "github.com/k8gb-io/k8gb/controllers/utils" gomock "go.uber.org/mock/gomock" endpoint "sigs.k8s.io/external-dns/endpoint" ) @@ -60,45 +61,45 @@ func (m *MockProvider) EXPECT() *MockProviderMockRecorder { } // CreateZoneDelegationForExternalDNS mocks base method. -func (m *MockProvider) CreateZoneDelegationForExternalDNS(arg0 *v1beta1.Gslb) error { +func (m *MockProvider) CreateZoneDelegationForExternalDNS(arg0 *v1beta1.Gslb, arg1 utils.DNSZone) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateZoneDelegationForExternalDNS", arg0) + ret := m.ctrl.Call(m, "CreateZoneDelegationForExternalDNS", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // CreateZoneDelegationForExternalDNS indicates an expected call of CreateZoneDelegationForExternalDNS. -func (mr *MockProviderMockRecorder) CreateZoneDelegationForExternalDNS(arg0 any) *gomock.Call { +func (mr *MockProviderMockRecorder) CreateZoneDelegationForExternalDNS(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateZoneDelegationForExternalDNS", reflect.TypeOf((*MockProvider)(nil).CreateZoneDelegationForExternalDNS), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateZoneDelegationForExternalDNS", reflect.TypeOf((*MockProvider)(nil).CreateZoneDelegationForExternalDNS), arg0, arg1) } // Finalize mocks base method. -func (m *MockProvider) Finalize(arg0 *v1beta1.Gslb) error { +func (m *MockProvider) Finalize(arg0 *v1beta1.Gslb, arg1 utils.DNSZone) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Finalize", arg0) + ret := m.ctrl.Call(m, "Finalize", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // Finalize indicates an expected call of Finalize. -func (mr *MockProviderMockRecorder) Finalize(arg0 any) *gomock.Call { +func (mr *MockProviderMockRecorder) Finalize(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Finalize", reflect.TypeOf((*MockProvider)(nil).Finalize), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Finalize", reflect.TypeOf((*MockProvider)(nil).Finalize), arg0, arg1) } // GetExternalTargets mocks base method. -func (m *MockProvider) GetExternalTargets(arg0 string) assistant.Targets { +func (m *MockProvider) GetExternalTargets(arg0 string, arg1 utils.DNSZone) assistant.Targets { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetExternalTargets", arg0) + ret := m.ctrl.Call(m, "GetExternalTargets", arg0, arg1) ret0, _ := ret[0].(assistant.Targets) return ret0 } // GetExternalTargets indicates an expected call of GetExternalTargets. -func (mr *MockProviderMockRecorder) GetExternalTargets(arg0 any) *gomock.Call { +func (mr *MockProviderMockRecorder) GetExternalTargets(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExternalTargets", reflect.TypeOf((*MockProvider)(nil).GetExternalTargets), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExternalTargets", reflect.TypeOf((*MockProvider)(nil).GetExternalTargets), arg0, arg1) } // SaveDNSEndpoint mocks base method. diff --git a/controllers/providers/dns/dns.go b/controllers/providers/dns/dns.go index dfa282bf35..611eaa1506 100644 --- a/controllers/providers/dns/dns.go +++ b/controllers/providers/dns/dns.go @@ -21,18 +21,19 @@ Generated by GoLic, for more details see: https://github.com/AbsaOSS/golic import ( k8gbv1beta1 "github.com/k8gb-io/k8gb/api/v1beta1" "github.com/k8gb-io/k8gb/controllers/providers/assistant" + "github.com/k8gb-io/k8gb/controllers/utils" externaldns "sigs.k8s.io/external-dns/endpoint" ) type Provider interface { // CreateZoneDelegationForExternalDNS handles delegated zone in Edge DNS - CreateZoneDelegationForExternalDNS(*k8gbv1beta1.Gslb) error + CreateZoneDelegationForExternalDNS(*k8gbv1beta1.Gslb, utils.DNSZone) error // GetExternalTargets retrieves list of external targets for specified host - GetExternalTargets(string) assistant.Targets + GetExternalTargets(string, utils.DNSZone) assistant.Targets // SaveDNSEndpoint update DNS endpoint in gslb or create new one if doesn't exist SaveDNSEndpoint(*k8gbv1beta1.Gslb, *externaldns.DNSEndpoint) error // Finalize finalize gslb in k8gbNamespace - Finalize(*k8gbv1beta1.Gslb) error + Finalize(*k8gbv1beta1.Gslb, utils.DNSZone) error // String see: Stringer interface String() string } diff --git a/controllers/providers/dns/empty.go b/controllers/providers/dns/empty.go index fd2e7dafa6..b8028bb62b 100644 --- a/controllers/providers/dns/empty.go +++ b/controllers/providers/dns/empty.go @@ -22,6 +22,7 @@ import ( k8gbv1beta1 "github.com/k8gb-io/k8gb/api/v1beta1" "github.com/k8gb-io/k8gb/controllers/depresolver" "github.com/k8gb-io/k8gb/controllers/providers/assistant" + "github.com/k8gb-io/k8gb/controllers/utils" externaldns "sigs.k8s.io/external-dns/endpoint" ) @@ -38,19 +39,19 @@ func NewEmptyDNS(config depresolver.Config, assistant assistant.Assistant) *Empt } } -func (p *EmptyDNSProvider) CreateZoneDelegationForExternalDNS(*k8gbv1beta1.Gslb) (err error) { +func (p *EmptyDNSProvider) CreateZoneDelegationForExternalDNS(*k8gbv1beta1.Gslb, utils.DNSZone) (err error) { return } -func (p *EmptyDNSProvider) GetExternalTargets(host string) (targets assistant.Targets) { - return p.assistant.GetExternalTargets(host, p.config.GetExternalClusterNSNames()) +func (p *EmptyDNSProvider) GetExternalTargets(host string, zone utils.DNSZone) (targets assistant.Targets) { + return p.assistant.GetExternalTargets(host, p.config.GetExternalClusterNSNames(zone)) } func (p *EmptyDNSProvider) SaveDNSEndpoint(gslb *k8gbv1beta1.Gslb, i *externaldns.DNSEndpoint) error { return p.assistant.SaveDNSEndpoint(gslb.Namespace, i) } -func (p *EmptyDNSProvider) Finalize(gslb *k8gbv1beta1.Gslb) (err error) { +func (p *EmptyDNSProvider) Finalize(gslb *k8gbv1beta1.Gslb, _ utils.DNSZone) (err error) { return p.assistant.RemoveEndpoint(gslb.Name) } diff --git a/controllers/providers/dns/external.go b/controllers/providers/dns/external.go index 31823fb0b2..15c468096d 100644 --- a/controllers/providers/dns/external.go +++ b/controllers/providers/dns/external.go @@ -24,6 +24,7 @@ import ( "strings" "github.com/k8gb-io/k8gb/controllers/logging" + "github.com/k8gb-io/k8gb/controllers/utils" assistant2 "github.com/k8gb-io/k8gb/controllers/providers/assistant" @@ -51,13 +52,13 @@ func NewExternalDNS(config depresolver.Config, assistant assistant2.Assistant) * } } -func (p *ExternalDNSProvider) CreateZoneDelegationForExternalDNS(gslb *k8gbv1beta1.Gslb) error { +func (p *ExternalDNSProvider) CreateZoneDelegationForExternalDNS(gslb *k8gbv1beta1.Gslb, zone utils.DNSZone) error { ttl := externaldns.TTL(gslb.Spec.Strategy.DNSTtlSeconds) log.Info(). Interface("provider", p). Msg("Creating/Updating DNSEndpoint CRDs") - NSServerList := []string{p.config.GetClusterNSName()} - for _, v := range p.config.GetExternalClusterNSNames() { + NSServerList := []string{p.config.GetClusterNSName(zone)} + for _, v := range p.config.GetExternalClusterNSNames(zone) { NSServerList = append(NSServerList, v) } sort.Strings(NSServerList) @@ -80,13 +81,13 @@ func (p *ExternalDNSProvider) CreateZoneDelegationForExternalDNS(gslb *k8gbv1bet Spec: externaldns.DNSEndpointSpec{ Endpoints: []*externaldns.Endpoint{ { - DNSName: p.config.DNSZone, + DNSName: zone.Zone, RecordTTL: ttl, RecordType: "NS", Targets: NSServerList, }, { - DNSName: p.config.GetClusterNSName(), + DNSName: p.config.GetClusterNSName(zone), RecordTTL: ttl, RecordType: "A", Targets: NSServerIPs, @@ -101,12 +102,12 @@ func (p *ExternalDNSProvider) CreateZoneDelegationForExternalDNS(gslb *k8gbv1bet return nil } -func (p *ExternalDNSProvider) Finalize(*k8gbv1beta1.Gslb) error { +func (p *ExternalDNSProvider) Finalize(*k8gbv1beta1.Gslb, utils.DNSZone) error { return p.assistant.RemoveEndpoint(p.endpointName) } -func (p *ExternalDNSProvider) GetExternalTargets(host string) (targets assistant2.Targets) { - return p.assistant.GetExternalTargets(host, p.config.GetExternalClusterNSNames()) +func (p *ExternalDNSProvider) GetExternalTargets(host string, zone utils.DNSZone) (targets assistant2.Targets) { + return p.assistant.GetExternalTargets(host, p.config.GetExternalClusterNSNames(zone)) } func (p *ExternalDNSProvider) SaveDNSEndpoint(gslb *k8gbv1beta1.Gslb, i *externaldns.DNSEndpoint) error { diff --git a/controllers/providers/dns/external_test.go b/controllers/providers/dns/external_test.go index fa4ad3ecba..9540952618 100644 --- a/controllers/providers/dns/external_test.go +++ b/controllers/providers/dns/external_test.go @@ -67,8 +67,12 @@ var a = struct { Port: 53, }, }, - EdgeDNSZone: "example.com", - DNSZone: "cloud.example.com", + DNSZones: []utils2.DNSZone{ + { + EdgeZone: "example.com", + Zone: "cloud.example.com", + }, + }, K8gbNamespace: "k8gb", }, Gslb: func() *k8gbv1beta1.Gslb { @@ -95,7 +99,7 @@ var expectedDNSEndpoint = &externaldns.DNSEndpoint{ Spec: externaldns.DNSEndpointSpec{ Endpoints: []*externaldns.Endpoint{ { - DNSName: a.Config.DNSZone, + DNSName: a.Config.DNSZones[0].Zone, RecordTTL: 30, RecordType: "NS", Targets: a.TargetNSNamesSorted, @@ -123,7 +127,8 @@ func TestCreateZoneDelegationOnExternalDNS(t *testing.T) { }) // act - err := p.CreateZoneDelegationForExternalDNS(a.Gslb) + zone := a.Config.DNSZones[0] + err := p.CreateZoneDelegationForExternalDNS(a.Gslb, zone) // assert assert.NoError(t, err) } diff --git a/controllers/providers/dns/infoblox.go b/controllers/providers/dns/infoblox.go index 1565492ed4..81dde3e331 100644 --- a/controllers/providers/dns/infoblox.go +++ b/controllers/providers/dns/infoblox.go @@ -30,6 +30,7 @@ import ( "github.com/k8gb-io/k8gb/controllers/depresolver" "github.com/k8gb-io/k8gb/controllers/providers/assistant" "github.com/k8gb-io/k8gb/controllers/providers/metrics" + "github.com/k8gb-io/k8gb/controllers/utils" ) type InfobloxProvider struct { @@ -48,19 +49,19 @@ func NewInfobloxDNS(config depresolver.Config, assistant assistant.Assistant, cl } } -func (p *InfobloxProvider) sanitizeDelegateZone(local, upstream []ibcl.NameServer) []ibcl.NameServer { +func (p *InfobloxProvider) sanitizeDelegateZone(local, upstream []ibcl.NameServer, zone utils.DNSZone) []ibcl.NameServer { // Drop own records for straight away update // And ensure local entries are up to date // And final list is sorted final := local - remote := p.filterOutDelegateTo(upstream, p.config.GetClusterNSName()) + remote := p.filterOutDelegateTo(upstream, p.config.GetClusterNSName(zone)) final = append(final, remote...) sortZones(final) return final } -func (p *InfobloxProvider) CreateZoneDelegationForExternalDNS(gslb *k8gbv1beta1.Gslb) error { +func (p *InfobloxProvider) CreateZoneDelegationForExternalDNS(gslb *k8gbv1beta1.Gslb, zone utils.DNSZone) error { objMgr, err := p.client.GetObjectManager() if err != nil { m.InfobloxIncrementZoneUpdateError(gslb) @@ -80,18 +81,18 @@ func (p *InfobloxProvider) CreateZoneDelegationForExternalDNS(gslb *k8gbv1beta1. var delegateTo []ibcl.NameServer for _, address := range addresses { - nameServer := ibcl.NameServer{Address: address, Name: p.config.GetClusterNSName()} + nameServer := ibcl.NameServer{Address: address, Name: p.config.GetClusterNSName(zone)} delegateTo = append(delegateTo, nameServer) } - findZone, err := p.getZoneDelegated(objMgr, p.config.DNSZone) + findZone, err := p.getZoneDelegated(objMgr, zone.Zone) if err != nil { m.InfobloxIncrementZoneUpdateError(gslb) return err } if findZone != nil { - err = p.checkZoneDelegated(findZone) + err = p.checkZoneDelegated(findZone, zone) if err != nil { m.InfobloxIncrementZoneUpdateError(gslb) return err @@ -100,12 +101,12 @@ func (p *InfobloxProvider) CreateZoneDelegationForExternalDNS(gslb *k8gbv1beta1. if len(findZone.Ref) > 0 { sortZones(findZone.DelegateTo) - currentList := p.sanitizeDelegateZone(delegateTo, findZone.DelegateTo) + currentList := p.sanitizeDelegateZone(delegateTo, findZone.DelegateTo, zone) // Drop external records if they are stale - extClusterHeartbeatFQDNs := p.config.GetExternalClusterHeartbeatFQDNs(gslb.Name) + extClusterHeartbeatFQDNs := p.config.GetExternalClusterHeartbeatFQDNs(gslb.Name, zone) if p.config.SplitBrainCheck { - for extClusterGeoTag, nsServerNameExt := range p.config.GetExternalClusterNSNames() { + for extClusterGeoTag, nsServerNameExt := range p.config.GetExternalClusterNSNames(zone) { err = p.assistant.InspectTXTThreshold( extClusterHeartbeatFQDNs[extClusterGeoTag], time.Second*time.Duration(gslb.Spec.Strategy.SplitBrainThresholdSeconds)) @@ -124,7 +125,7 @@ func (p *InfobloxProvider) CreateZoneDelegationForExternalDNS(gslb *k8gbv1beta1. Interface("records", findZone.DelegateTo). Msg("Found delegated zone records") log.Info(). - Str("DNSZone", p.config.DNSZone). + Str("DNSZone", zone.Zone). Interface("serverList", currentList). Msg("Updating delegated zone with the server list") _, err = p.updateZoneDelegated(objMgr, findZone.Ref, currentList) @@ -137,13 +138,13 @@ func (p *InfobloxProvider) CreateZoneDelegationForExternalDNS(gslb *k8gbv1beta1. } } else { log.Info(). - Str("DNSZone", p.config.DNSZone). + Str("DNSZone", zone.Zone). Msg("Creating delegated zone") sortZones(delegateTo) log.Debug(). Interface("records", delegateTo). Msg("Delegated records") - _, err = p.createZoneDelegated(objMgr, p.config.DNSZone, delegateTo) + _, err = p.createZoneDelegated(objMgr, zone.Zone, delegateTo) if err != nil { m.InfobloxIncrementZoneUpdateError(gslb) return err @@ -151,29 +152,29 @@ func (p *InfobloxProvider) CreateZoneDelegationForExternalDNS(gslb *k8gbv1beta1. m.InfobloxIncrementZoneUpdate(gslb) } if p.config.SplitBrainCheck { - return p.saveHeartbeatTXTRecord(objMgr, gslb) + return p.saveHeartbeatTXTRecord(objMgr, gslb, zone) } return nil } -func (p *InfobloxProvider) Finalize(gslb *k8gbv1beta1.Gslb) error { +func (p *InfobloxProvider) Finalize(gslb *k8gbv1beta1.Gslb, zone utils.DNSZone) error { objMgr, err := p.client.GetObjectManager() if err != nil { return err } - findZone, err := p.getZoneDelegated(objMgr, p.config.DNSZone) + findZone, err := p.getZoneDelegated(objMgr, zone.Zone) if err != nil { return err } if findZone != nil { - err = p.checkZoneDelegated(findZone) + err = p.checkZoneDelegated(findZone, zone) if err != nil { return err } if len(findZone.Ref) > 0 { log.Info(). - Str("DNSZone", p.config.DNSZone). + Str("DNSZone", zone.Zone). Msg("Deleting delegated zone") _, err := p.deleteZoneDelegated(objMgr, findZone.Ref) if err != nil { @@ -182,7 +183,7 @@ func (p *InfobloxProvider) Finalize(gslb *k8gbv1beta1.Gslb) error { } } - heartbeatTXTName := p.config.GetClusterHeartbeatFQDN(gslb.Name) + heartbeatTXTName := p.config.GetClusterHeartbeatFQDN(gslb.Name, zone) findTXT, err := p.getTXTRecord(objMgr, heartbeatTXTName) if err != nil { return err @@ -202,8 +203,8 @@ func (p *InfobloxProvider) Finalize(gslb *k8gbv1beta1.Gslb) error { return nil } -func (p *InfobloxProvider) GetExternalTargets(host string) (targets assistant.Targets) { - return p.assistant.GetExternalTargets(host, p.config.GetExternalClusterNSNames()) +func (p *InfobloxProvider) GetExternalTargets(host string, zone utils.DNSZone) (targets assistant.Targets) { + return p.assistant.GetExternalTargets(host, p.config.GetExternalClusterNSNames(zone)) } func (p *InfobloxProvider) SaveDNSEndpoint(gslb *k8gbv1beta1.Gslb, i *externaldns.DNSEndpoint) error { @@ -214,10 +215,10 @@ func (p *InfobloxProvider) String() string { return "Infoblox" } -func (p *InfobloxProvider) saveHeartbeatTXTRecord(objMgr *ibcl.ObjectManager, gslb *k8gbv1beta1.Gslb) (err error) { +func (p *InfobloxProvider) saveHeartbeatTXTRecord(objMgr *ibcl.ObjectManager, gslb *k8gbv1beta1.Gslb, zone utils.DNSZone) (err error) { var heartbeatTXTRecord *ibcl.RecordTXT edgeTimestamp := fmt.Sprint(time.Now().UTC().Format("2006-01-02T15:04:05")) - heartbeatTXTName := p.config.GetClusterHeartbeatFQDN(gslb.Name) + heartbeatTXTName := p.config.GetClusterHeartbeatFQDN(gslb.Name, zone) heartbeatTXTRecord, err = p.getTXTRecord(objMgr, heartbeatTXTName) if err != nil { return @@ -226,7 +227,7 @@ func (p *InfobloxProvider) saveHeartbeatTXTRecord(objMgr *ibcl.ObjectManager, gs log.Info(). Str("HeartbeatTXTName", heartbeatTXTName). Msg("Creating split brain TXT record") - _, err = p.createTXTRecord(objMgr, heartbeatTXTName, edgeTimestamp, uint(gslb.Spec.Strategy.DNSTtlSeconds)) + _, err = p.createTXTRecord(objMgr, heartbeatTXTName, edgeTimestamp, uint(gslb.Spec.Strategy.DNSTtlSeconds)) //nolint:gosec if err != nil { m.InfobloxIncrementHeartbeatError(gslb) return @@ -245,9 +246,9 @@ func (p *InfobloxProvider) saveHeartbeatTXTRecord(objMgr *ibcl.ObjectManager, gs return } -func (p *InfobloxProvider) checkZoneDelegated(findZone *ibcl.ZoneDelegated) error { - if findZone.Fqdn != p.config.DNSZone { - err := fmt.Errorf("delegated zone returned from infoblox(%s) does not match requested gslb zone(%s)", findZone.Fqdn, p.config.DNSZone) +func (p *InfobloxProvider) checkZoneDelegated(findZone *ibcl.ZoneDelegated, zone utils.DNSZone) error { + if findZone.Fqdn != zone.Zone { + err := fmt.Errorf("delegated zone returned from infoblox(%s) does not match requested gslb zone(%s)", findZone.Fqdn, zone.Zone) return err } return nil diff --git a/controllers/providers/dns/infoblox_test.go b/controllers/providers/dns/infoblox_test.go index 82cfa264a3..837a487ca2 100644 --- a/controllers/providers/dns/infoblox_test.go +++ b/controllers/providers/dns/infoblox_test.go @@ -52,8 +52,12 @@ var ( Port: 53, }, }, - EdgeDNSZone: "example.com", - DNSZone: "cloud.example.com", + DNSZones: []utils.DNSZone{ + { + EdgeZone: "example.com", + Zone: "cloud.example.com", + }, + }, K8gbNamespace: "k8gb", Infoblox: depresolver.Infoblox{ Host: "fakeinfoblox.example.com", @@ -65,7 +69,7 @@ var ( } defaultDelegatedZone = ibclient.ZoneDelegated{ - Fqdn: defaultConfig.DNSZone, + Fqdn: defaultConfig.DNSZones[0].Zone, DelegateTo: []ibclient.NameServer{}, Ref: ref, } @@ -89,7 +93,6 @@ func TestCanFilterOutDelegatedZoneEntryAccordingFQDNProvided(t *testing.T) { {Address: "10.0.0.3", Name: "gslb-ns-eu-cloud.example.com"}, } customConfig := defaultConfig - customConfig.EdgeDNSZone = "example.com" customConfig.ExtClustersGeoTags = []string{"za"} a := assistant.NewGslbAssistant(nil, customConfig.K8gbNamespace, customConfig.EdgeDNSServers) ctrl := gomock.NewController(t) @@ -97,11 +100,13 @@ func TestCanFilterOutDelegatedZoneEntryAccordingFQDNProvided(t *testing.T) { m := mocks.NewMockInfobloxClient(ctrl) provider := NewInfobloxDNS(customConfig, a, m) // act - extClusters := customConfig.GetExternalClusterNSNames() + zone := customConfig.DNSZones[0] + extClusters := customConfig.GetExternalClusterNSNames(zone) got := provider.filterOutDelegateTo(delegateTo, extClusters["za"]) // assert assert.Equal(t, want, got, "got:\n %q filtered out delegation records,\n\n want:\n %q", got, want) } + func TestCanSanitizeDelegatedZone(t *testing.T) { // arrange local := []ibclient.NameServer{ @@ -126,7 +131,6 @@ func TestCanSanitizeDelegatedZone(t *testing.T) { {Address: "10.1.0.3", Name: "gslb-ns-za-cloud.example.com"}, } customConfig := defaultConfig - customConfig.EdgeDNSZone = "example.com" customConfig.ExtClustersGeoTags = []string{"za"} customConfig.ClusterGeoTag = "eu" a := assistant.NewGslbAssistant(nil, customConfig.K8gbNamespace, customConfig.EdgeDNSServers) @@ -135,7 +139,8 @@ func TestCanSanitizeDelegatedZone(t *testing.T) { m := mocks.NewMockInfobloxClient(ctrl) provider := NewInfobloxDNS(customConfig, a, m) // act - got := provider.sanitizeDelegateZone(local, upstream) + zone := customConfig.DNSZones[0] + got := provider.sanitizeDelegateZone(local, upstream, zone) // assert assert.Equal(t, want, got, "got:\n %q filtered out delegation records,\n\n want:\n %q", got, want) } @@ -176,7 +181,8 @@ func TestInfobloxCreateZoneDelegationForExternalDNS(t *testing.T) { provider := NewInfobloxDNS(config, a, cl) // act - err := provider.CreateZoneDelegationForExternalDNS(defaultGslb) + zone := defaultConfig.DNSZones[0] + err := provider.CreateZoneDelegationForExternalDNS(defaultGslb, zone) // assert assert.NoError(t, err) } @@ -204,7 +210,8 @@ func TestInfobloxCreateZoneDelegationForExternalDNSWithSplitBrainEnabled(t *test provider := NewInfobloxDNS(config, a, cl) // act - err := provider.CreateZoneDelegationForExternalDNS(defaultGslb) + zone := defaultConfig.DNSZones[0] + err := provider.CreateZoneDelegationForExternalDNS(defaultGslb, zone) // assert assert.NoError(t, err) } @@ -227,7 +234,8 @@ func TestInfobloxCreateZoneDelegationForExternalDNSWithSplitBrainEnabledCreating provider := NewInfobloxDNS(config, a, cl) // act - err := provider.CreateZoneDelegationForExternalDNS(defaultGslb) + zone := defaultConfig.DNSZones[0] + err := provider.CreateZoneDelegationForExternalDNS(defaultGslb, zone) // assert assert.NoError(t, err) } @@ -253,7 +261,8 @@ func TestInfobloxFinalize(t *testing.T) { provider := NewInfobloxDNS(config, a, cl) // act - err := provider.Finalize(defaultGslb) + zone := defaultConfig.DNSZones[0] + err := provider.Finalize(defaultGslb, zone) // assert assert.NoError(t, err) diff --git a/controllers/providers/metrics/prometheus_test.go b/controllers/providers/metrics/prometheus_test.go index d71f49705b..457e7c2ab3 100644 --- a/controllers/providers/metrics/prometheus_test.go +++ b/controllers/providers/metrics/prometheus_test.go @@ -33,6 +33,7 @@ import ( "github.com/prometheus/client_golang/prometheus/testutil" "github.com/k8gb-io/k8gb/controllers/depresolver" + "github.com/k8gb-io/k8gb/controllers/utils" "github.com/stretchr/testify/assert" ) @@ -47,7 +48,7 @@ const ( var ( defaultGslb = new(k8gbv1beta1.Gslb) defaultEndpoint = new(externaldns.DNSEndpoint) - defaultConfig = depresolver.Config{K8gbNamespace: namespace, DNSZone: "cloud.example.com"} + defaultConfig = depresolver.Config{K8gbNamespace: namespace, DNSZones: []utils.DNSZone{{Zone: "cloud.example.com"}}} ) func TestMetricsSingletonIsNotNil(t *testing.T) { diff --git a/controllers/utils/dns.go b/controllers/utils/dns.go index 583380d2e5..9026bc5288 100644 --- a/controllers/utils/dns.go +++ b/controllers/utils/dns.go @@ -45,6 +45,25 @@ func (l DNSList) String() string { return strings.Join(aux, ",") } +type DNSZone struct { + EdgeZone string + Zone string +} + +type DNSZoneList []DNSZone + +func (s DNSZone) String() string { + return fmt.Sprintf("%s:%s", s.EdgeZone, s.Zone) +} + +func (l DNSZoneList) String() string { + var aux []string + for _, el := range l { + aux = append(aux, el.String()) + } + return strings.Join(aux, ",") +} + // Dig returns a list of IP addresses for a given FQDN by using the dns servers from edgeDNSServers // dns servers are tried one by one from the edgeDNSServers and if there is a non-error response it is returned and the rest is not tried func Dig(fqdn string, edgeDNSServers ...DNSServer) (ips []string, err error) { diff --git a/go.sum b/go.sum index e7b4795d69..8c7a0b03ef 100644 --- a/go.sum +++ b/go.sum @@ -183,10 +183,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4= -github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= -github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= -github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -196,8 +192,8 @@ github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= @@ -218,48 +214,22 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= -go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= -go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= -go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0 h1:lsInsfvhVIfOI6qHVyysXMNDnjO9Npvl7tlDPJFBVd4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.30.0/go.mod h1:KQsVNh4OjgjTG0G6EiNi1jVpnaeeKsKMRwbLN+f1+8M= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 h1:JAv0Jwtl01UFiyWZEMiJZBiTlv5A50zNs8lsthXqIio= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0/go.mod h1:QNKLmUEAq2QUbPQUfvw4fmv0bgbK7UlOSFCnXyfvSNc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0 h1:umZgi92IyxfXd/l4kaDhnKgY8rnN/cZcF1LKc6I8OQ8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.30.0/go.mod h1:4lVs6obhSVRb1EW5FhOuBTyiQhtRtAnnva9vD3yRfq8= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4= -go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= -go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= -go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= -go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/sdk v1.29.0 h1:vkqKjk7gwhS8VaWb0POZKmIEDimRCMsopNYnriHyryo= -go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= -go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= -go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= -go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= -go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= -go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= -go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -282,10 +252,6 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -315,18 +281,10 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -335,10 +293,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -367,25 +321,13 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd h1:BBOTEWLuuEGQy9n1y9MhVJ9Qt0BDu21X8qZs71/uPZo= -google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:fO8wJzT2zbQbAjbIoos1285VfEIYKDDY+Dt+WpTkh6g= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd h1:6TEm2ZxXoQmFWFlt1vNxvVOa1Q0dXFQD1m/rYjXmS0E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240822170219-fc7c04adadcd/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM= -google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -397,8 +339,6 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -423,20 +363,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -istio.io/api v1.22.4-0.20240808015337-e0ff1ca45c33 h1:/IeYCiL05FL8ZxndwibKznhLsrZRDH0xaHwsk/roU7I= -istio.io/api v1.22.4-0.20240808015337-e0ff1ca45c33/go.mod h1:S3l8LWqNYS9yT+d4bH+jqzH2lMencPkW7SKM1Cu9EyM= -istio.io/api v1.23.1-0.20240821135524-978ac3b543c0 h1:WO2cBln4Hjm+M8S8wExj+g/eZ46cFaqoJSLgdTwKWOk= -istio.io/api v1.23.1-0.20240821135524-978ac3b543c0/go.mod h1:QPSTGXuIQdnZFEm3myf9NZ5uBMwCdJWUvfj9ZZ+2oBM= -istio.io/api v1.23.1-0.20240906150629-ba126bb830f0 h1:utRdmZryJWw71X1flREUJFLk56QCl2JdVuP3xsvDcMI= -istio.io/api v1.23.1-0.20240906150629-ba126bb830f0/go.mod h1:QPSTGXuIQdnZFEm3myf9NZ5uBMwCdJWUvfj9ZZ+2oBM= istio.io/api v1.23.3-0.20241007150425-eb56b2cffca7 h1:c8RwLi4qSqCn36t5B2WFkwRDY+qPZ1XhlLMEIoJDCcs= istio.io/api v1.23.3-0.20241007150425-eb56b2cffca7/go.mod h1:QPSTGXuIQdnZFEm3myf9NZ5uBMwCdJWUvfj9ZZ+2oBM= -istio.io/client-go v1.22.4 h1:55aKo0iDD/IZmz0HU0f0UjOeTO4bg43DLnfASYD2lq4= -istio.io/client-go v1.22.4/go.mod h1:pCCBfkXZVAxptGlL5gdGIonPxFsNQZ+iBxvYIUF9z7c= -istio.io/client-go v1.23.1 h1:IX2cgUUXnVYo+9H6bFGSp/vuKVLPUkmiN8qk1/mvsYs= -istio.io/client-go v1.23.1/go.mod h1:+fxu+O2GkITM3HEREUWdobvRXqI/UhAAI7hfxqqpRh0= -istio.io/client-go v1.23.2 h1:BIt6A+KaUOFin3SzXiDq2Fr/TMBev1+c836R0BfUfhU= -istio.io/client-go v1.23.2/go.mod h1:E08wpMtUulJk2tlWOCUVakjy1bKFxUNm22tM1R1QY0Y= istio.io/client-go v1.23.3 h1:rs+mO4A+NaXVcZgDO0RRZE7KRAlDooq2PSkxl7tevig= istio.io/client-go v1.23.3/go.mod h1:Lfa3anzx7/kCOpcAciR+JiRMj/SYuzDcbXQDjkThnLg= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= @@ -459,8 +387,6 @@ k8s.io/kube-openapi v0.0.0-20240423202451-8948a665c108 h1:Q8Z7VlGhcJgBHJHYugJ/K/ k8s.io/kube-openapi v0.0.0-20240423202451-8948a665c108/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= -sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/controller-runtime v0.19.1 h1:Son+Q40+Be3QWb+niBXAg2vFiYWolDjjRfO8hn/cxOk= sigs.k8s.io/controller-runtime v0.19.1/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/external-dns v0.14.2 h1:j7rYtQqDAxYfN9N1/BZcRdzUBRsnZp4tZcuZ75ekTlc=