Skip to content

Add support for multiple zones #1845

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions chart/k8gb/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ Create the name of the service account to use
{{- if .Values.route53.enabled -}}
k8gb-{{ .Values.route53.hostedZoneID }}-{{ .Values.k8gb.clusterGeoTag }}
{{- else -}}
k8gb-{{ .Values.k8gb.dnsZone }}-{{ .Values.k8gb.clusterGeoTag }}
k8gb-{{ index (split ":" (index (split ";" (include "k8gb.dnsZonesString" .)) "_0")) "_1" }}-{{ .Values.k8gb.clusterGeoTag }}
{{- end -}}
{{- end -}}

Expand All @@ -96,6 +96,29 @@ k8gb-{{ .Values.k8gb.dnsZone }}-{{ .Values.k8gb.clusterGeoTag }}
{{- end -}}
{{- end -}}

{{- define "k8gb.dnsZonesString" -}}
{{- $entries := list -}}
{{- range .Values.k8gb.dnsZones }}
{{- $dnsZoneNegTTL := toString (.dnsZoneNegTTL | default "300") }}
{{- $entry := printf "%s:%s:%s" .zone .domain $dnsZoneNegTTL }}
{{- $entries = append $entries $entry }}
{{- end }}
{{- if and (or (not .Values.k8gb.dnsZones) (eq (len .Values.k8gb.dnsZones) 0)) .Values.k8gb.dnsZone .Values.k8gb.edgeDNSZone }}
{{- $extraEntry := printf "%s:%s:%s" .Values.k8gb.edgeDNSZone .Values.k8gb.dnsZone "300" }}
{{- $entries = append $entries $extraEntry }}
{{- end }}
{{- join ";" $entries }}
{{- end }}


{{- define "k8gb.coredns.extraPlugins" -}}
{{- if .Values.k8gb.coredns.extra_plugins }}
{{- range .Values.k8gb.coredns.extra_plugins }}
{{ . }}
{{- end }}
{{- end }}
{{- end }}

{{- define "k8gb.extdnsProviderOpts" -}}
{{- if .Values.ns1.enabled -}}
{{- if .Values.ns1.endpoint -}}
Expand Down Expand Up @@ -139,7 +162,13 @@ k8gb-{{ .Values.k8gb.dnsZone }}-{{ .Values.k8gb.clusterGeoTag }}
- --rfc2136-{{ $kk }}={{ $vv }}
{{- end }}
{{- end }}
- --rfc2136-zone={{ .Values.k8gb.edgeDNSZone }}
{{- $dnsZonesRaw := include "k8gb.dnsZonesString" . }}
{{- $dnsZones := split ";" $dnsZonesRaw }}
{{- range $dnsZones }}
{{- $parts := split ":" . }}
{{- $zone := index $parts "_0" }}
- --rfc2136-zone={{ $zone }}
{{- end }}
env:
- name: EXTERNAL_DNS_RFC2136_TSIG_SECRET
valueFrom:
Expand Down
15 changes: 11 additions & 4 deletions chart/k8gb/templates/coredns/cm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@ metadata:
{{ include "chart.labels" . | indent 4 }}
data:
Corefile: |-
{{ .Values.k8gb.dnsZone }}:5353 {
{{- $dnsZonesRaw := include "k8gb.dnsZonesString" . }}
{{- $dnsZones := split ";" $dnsZonesRaw }}
{{- range $dnsZones }}
{{- $parts := split ":" . }}
{{- $domain := index $parts "_1" }}
{{- $dnsZoneNegTTL := index $parts "_2" }}
{{ $domain }}:5353 {
errors
health
{{- if .Values.k8gb.coredns.extra_plugins }}
{{- range .Values.k8gb.coredns.extra_plugins }}
{{- if $.Values.k8gb.coredns.extra_plugins }}
{{- range $.Values.k8gb.coredns.extra_plugins }}
{{ . }}
{{- end }}
{{- end }}
Expand All @@ -21,10 +27,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 }}
Expand Down
6 changes: 2 additions & 4 deletions chart/k8gb/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,10 @@ spec:
value: {{ quote .Values.k8gb.clusterGeoTag }}
- name: EXT_GSLB_CLUSTERS_GEO_TAGS
value: {{ quote .Values.k8gb.extGslbClustersGeoTags }}
- name: EDGE_DNS_ZONE
value: {{ .Values.k8gb.edgeDNSZone }}
- name: EDGE_DNS_SERVERS
value: {{ include "k8gb.edgeDNSServers" . }}
- name: DNS_ZONE
value: {{ .Values.k8gb.dnsZone }}
- name: DNS_ZONES
value: {{ include "k8gb.dnsZonesString" . }}
- name: RECONCILE_REQUEUE_SECONDS
value: {{ quote .Values.k8gb.reconcileRequeueSeconds }}
- name: NS_RECORD_TTL
Expand Down
8 changes: 7 additions & 1 deletion chart/k8gb/templates/external-dns/external-dns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ spec:
image: {{ .Values.externaldns.image }}
args:
- --source=crd
- --domain-filter={{ .Values.k8gb.edgeDNSZone }} # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
{{- $dnsZonesRaw := include "k8gb.dnsZonesString" . }}
{{- $dnsZones := split ";" $dnsZonesRaw }}
{{- range $dnsZones }}
{{- $parts := split ":" . }}
{{- $zone := index $parts "_0" }}
- --domain-filter={{ $zone }} # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
{{- end }}
- --policy=sync # enable full synchronization including record removal
- --log-level=debug # debug only
- --managed-record-types=A
Expand Down
52 changes: 46 additions & 6 deletions chart/k8gb/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,12 @@
"deployRbac": {
"type": "boolean"
},
"dnsZones": {
"type": "array",
"items": {
"$ref": "#/definitions/k8gbDnsZone"
}
},
"dnsZone": {
"format": "idn-hostname",
"minLength": 1
Expand Down Expand Up @@ -334,12 +340,24 @@
"type": "object"
}
},
"required": [
"clusterGeoTag",
"extGslbClustersGeoTags",
"dnsZone",
"edgeDNSServers",
"edgeDNSZone"
"oneOf": [
{
"required": [
"clusterGeoTag",
"extGslbClustersGeoTags",
"edgeDNSServers",
"dnsZone",
"edgeDNSZone"
]
},
{
"required": [
"clusterGeoTag",
"extGslbClustersGeoTags",
"edgeDNSServers",
"dnsZones"
]
}
],
"title": "k8gb"
},
Expand Down Expand Up @@ -421,6 +439,28 @@
}
}
},
"k8gbDnsZone": {
"type": "object",
"properties": {
"zone": {
"type": "string",
"format": "idn-hostname"
},
"domain": {
"type": "string",
"format": "idn-hostname"
},
"dnsZoneNegTTL": {
"type": "integer",
"minimum": 0,
"default": 300
}
},
"required": [
"zone",
"domain"
]
},
"Ns1": {
"type": "object",
"additionalProperties": false,
Expand Down
22 changes: 15 additions & 7 deletions chart/k8gb/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,21 @@ 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
# -- host/ip[:port] format is supported here where port defaults to 53
# DNSZones - For backward compatibility, the dnsZone and edgeDNSZone fields are allowed; otherwise,
# the dnsZones array is used. For valid values, use either dnsZone and edgeDNSZone or dnsZones.
#
# -- dnsZone: deprecated
# dnsZone: "cloud.example.com"
# -- edgeDNSZone: deprecated
# edgeDNSZone: "example.com"
# -- array of dns zones controlled by gslb§
dnsZones:
- zone: "example.com" # -- main zone which would contain gslb zone to delegate (same meaning as to edgeDNSZone)
domain: "cloud.example.com" # -- domain controlled by gslb (same meaning as to dnsZone)
dnsZoneNegTTL: 30 # -- Negative TTL for SOA record# -- host/ip[:port] format is supported here where port defaults to 53
# - zone: "example.org" # -- main zone which would contain gslb zone to delegate (same meaning as to edgeDNSZone)
# domain: "cloud.example.org" # -- domain controlled by gslb (same meaning as to dnsZone)
# dnsZoneNegTTL: 50 # -- Negative TTL for SOA record# -- 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
- "1.1.1.1"
Expand Down
16 changes: 10 additions & 6 deletions controllers/depresolver/depresolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ type Config struct {
NSRecordTTL int `env:"NS_RECORD_TTL, default=30"`
// ClusterGeoTag to determine specific location
ClusterGeoTag string `env:"CLUSTER_GEO_TAG"`
// ExtClustersGeoTags to identify clusters in other locations in format separated by comma. i.e.: "eu,uk,us"
ExtClustersGeoTags []string `env:"EXT_GSLB_CLUSTERS_GEO_TAGS, default=[]"`
// extClustersGeoTags to identify clusters in other locations in format separated by comma. i.e.: "eu,uk,us"
extClustersGeoTags []string `env:"EXT_GSLB_CLUSTERS_GEO_TAGS, default=[]"`
// EdgeDNSType is READONLY and is set automatically by configuration
EdgeDNSType EdgeDNSType
// EdgeDNSServers
Expand All @@ -134,10 +134,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"`
// EdgeDNSZone main zone which would contain gslb zone to delegate; e.g. example.com
EdgeDNSZone string `env:"EDGE_DNS_ZONE"`
// DNSZone controlled by gslb; e.g. cloud.example.com
DNSZone string `env:"DNS_ZONE"`
// edgeDNSZone main zone which would contain gslb zone to delegate; e.g. example.com
edgeDNSZone string `env:"EDGE_DNS_ZONE"`
// dnsZone controlled by gslb; e.g. cloud.example.com
dnsZone string `env:"DNS_ZONE"`
// DelegationZones
DelegationZones DelegationZones
// DelegationZones pairs of dnsZone ad edgeDNSZone, eg: DNS_ZONES=example.com:cloud.example.com;example.io:cloud.example.io
dnsZones string `env:"DNS_ZONES"`
// K8gbNamespace k8gb namespace
K8gbNamespace string `env:"POD_NAMESPACE"`
// Infoblox configuration
Expand Down
51 changes: 34 additions & 17 deletions controllers/depresolver/depresolver_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ import (
"github.com/rs/zerolog"
)

// TODO: refactor with kong.CLI to read envvars into Config
// TODO: refactor with go-playground/validator to validate
// TODO: Remove EdgeDNSZone and DNSZone from Config

// Environment variables keys
const (
ReconcileRequeueSecondsKey = "RECONCILE_REQUEUE_SECONDS"
Expand All @@ -41,6 +45,7 @@ const (
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"
Expand Down Expand Up @@ -69,6 +74,12 @@ const (
EdgeDNSServerPortKey = "EDGE_DNS_SERVER_PORT"
)

const (
localhost = "localhost"

localhostIPv4 = "127.0.0.1"
)

// ResolveOperatorConfig executes once. It reads operator's configuration
// from environment variables into &Config and validates
func (dr *DependencyResolver) ResolveOperatorConfig() (*Config, error) {
Expand All @@ -87,13 +98,17 @@ 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)
dr.config.ExtClustersGeoTags = excludeGeoTag(dr.config.ExtClustersGeoTags, dr.config.ClusterGeoTag)
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))
dr.config.EdgeDNSType, recognizedDNSTypes = getEdgeDNSType(dr.config)

// validation
// replace validations by go-playground/validator
dr.errorConfig = dr.validateConfig(dr.config, recognizedDNSTypes)
// validation
if dr.errorConfig == nil {
dr.config.DelegationZones, dr.errorConfig = parseDelegationZones(dr.config)
}
})
return dr.config, dr.errorConfig
}
Expand Down Expand Up @@ -128,11 +143,11 @@ func (dr *DependencyResolver) validateConfig(config *Config, recognizedDNSTypes
if err != nil {
return err
}
err = field(ExtClustersGeoTagsKey, config.ExtClustersGeoTags).hasItems().hasUniqueItems().err
err = field(ExtClustersGeoTagsKey, config.extClustersGeoTags).hasItems().hasUniqueItems().err
if err != nil {
return err
}
for i, geoTag := range config.ExtClustersGeoTags {
for i, geoTag := range config.extClustersGeoTags {
err = field(fmt.Sprintf("%s[%v]", ExtClustersGeoTagsKey, i), geoTag).
isNotEmpty().matchRegexp(geoTagRegex).err
if err != nil {
Expand Down Expand Up @@ -160,11 +175,11 @@ 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
err = field(EdgeDNSZoneKey, config.edgeDNSZone).matchRegexp(hostNameRegex).err
if err != nil {
return err
}
err = field(DNSZoneKey, config.DNSZone).isNotEmpty().matchRegexp(hostNameRegex).err
err = field(DNSZoneKey, config.dnsZone).matchRegexp(hostNameRegex).err
if err != nil {
return err
}
Expand All @@ -185,12 +200,12 @@ func (dr *DependencyResolver) validateConfig(config *Config, recognizedDNSTypes
return nil
}

serverNames := config.GetExternalClusterNSNames()
serverNames[config.ClusterGeoTag] = config.GetClusterNSName()
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)
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)
Expand All @@ -215,7 +230,7 @@ func (dr *DependencyResolver) validateConfig(config *Config, recognizedDNSTypes
func validateLocalhostNotAmongDNSServers(config *Config) error {
containsLocalhost := func(list utils.DNSList) bool {
for i := 1; i < len(list); i++ { // skipping first because localhost or 127.0.0.1 can occur on the first position
if list[i].Host == "localhost" || list[i].Host == "127.0.0.1" {
if list[i].Host == localhost || list[i].Host == localhostIPv4 {
return true
}
}
Expand Down Expand Up @@ -370,20 +385,22 @@ func parseLogOutputFormat(value string) LogFormat {
return NoFormat
}

func (c *Config) GetExternalClusterNSNames() (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)
// deprecated, used for validations only
func (c *Config) getExternalClusterNSNames() (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)
}
return
}

func (c *Config) GetClusterNSName() string {
return getNsName(c.ClusterGeoTag, c.DNSZone, c.EdgeDNSZone, c.EdgeDNSServers[0].Host)
// deprecated, used for validations only
func (c *Config) getClusterNSName() string {
return getNsName(c.ClusterGeoTag, c.dnsZone, c.edgeDNSZone, c.EdgeDNSServers[0].Host)
}

// getNsName returns NS for geo tag.
// The values is combination of DNSZone, EdgeDNSZone and (Ext)ClusterGeoTag, see:
// The values is combination of dnsZone, edgeDNSZone and (Ext)ClusterGeoTag, see:
// DNS_ZONE k8gb-test.gslb.cloud.example.com
// EDGE_DNS_ZONE: cloud.example.com
// CLUSTER_GEOTAG: us
Expand Down
Loading
Loading