From ba7117c4eec1f17003971a1923968f89021c9303 Mon Sep 17 00:00:00 2001 From: "jakub.coufal" Date: Fri, 19 Mar 2021 15:46:43 +0100 Subject: [PATCH] Use existing Access annotation --- pkg/apis/externaldns/types.go | 2 +- source/service.go | 41 +++++++++++++++++++---------------- source/service_test.go | 35 ++++++++++++++++++++---------- source/source.go | 2 -- 4 files changed, 47 insertions(+), 33 deletions(-) diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 1e721a4a53..cace060f04 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -329,7 +329,7 @@ func (cfg *Config) ParseFlags(args []string) error { app.Flag("ignore-ingress-tls-spec", "Ignore tls spec section in ingresses resources, applicable only for ingress sources (optional, default: false)").BoolVar(&cfg.IgnoreIngressTLSSpec) app.Flag("compatibility", "Process annotation semantics from legacy implementations (optional, options: mate, molecule)").Default(defaultConfig.Compatibility).EnumVar(&cfg.Compatibility, "", "mate", "molecule") app.Flag("publish-internal-services", "Allow external-dns to publish DNS records for ClusterIP services (optional)").BoolVar(&cfg.PublishInternal) - app.Flag("publish-host-ip", "Allow external-dns to publish host-ip for headless services, optionally you could use 'external-dns.alpha.kubernetes.io/use-external-host-ip' annotation on the Service to control whether to publish ExternalIP of the Host Node or InternalIP which is a default (optional)").BoolVar(&cfg.PublishHostIP) + app.Flag("publish-host-ip", "Allow external-dns to publish host-ip for headless services, optionally you could use 'external-dns.alpha.kubernetes.io/access' annotation on the Service to control whether to publish ExternalIP of the Host Node or InternalIP which is a default (optional)").BoolVar(&cfg.PublishHostIP) app.Flag("always-publish-not-ready-addresses", "Always publish also not ready addresses for headless services (optional)").BoolVar(&cfg.AlwaysPublishNotReadyAddresses) app.Flag("connector-source-server", "The server to connect for connector source, valid only when using connector source").Default(defaultConfig.ConnectorSourceServer).StringVar(&cfg.ConnectorSourceServer) app.Flag("crd-source-apiversion", "API version of the CRD for crd source, e.g. `externaldns.k8s.io/v1alpha1`, valid only when using crd source").Default(defaultConfig.CRDSourceAPIVersion).StringVar(&cfg.CRDSourceAPIVersion) diff --git a/source/service.go b/source/service.go index b7b758f327..b4702440a3 100644 --- a/source/service.go +++ b/source/service.go @@ -308,23 +308,22 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri for _, headlessDomain := range headlessDomains { var ep []string if sc.publishHostIP { - if _, ok := svc.Annotations[externalIPAnnotationKey]; ok { - node, err := sc.nodeInformer.Lister().Get(pod.Spec.NodeName) - if err != nil { - return nil - } - var externalIPs endpoint.Targets - for _, address := range node.Status.Addresses { - if address.Type == v1.NodeExternalIP { - externalIPs = append(externalIPs, address.Address) - } + internalIPs := []string{pod.Status.HostIP} + var externalIPs endpoint.Targets + + node, err := sc.nodeInformer.Lister().Get(pod.Spec.NodeName) + if err != nil { + log.Errorf("Node %s not found", pod.Spec.NodeName) + return nil + } + for _, address := range node.Status.Addresses { + if address.Type == v1.NodeExternalIP { + externalIPs = append(externalIPs, address.Address) } - ep = append(ep, externalIPs...) - log.Debugf("Generating matching endpoint %s with Host ExternalIPs %v", headlessDomain, externalIPs) - } else { - ep = append(ep, pod.Status.HostIP) - log.Debugf("Generating matching endpoint %s with HostIP %s", headlessDomain, ep) } + + access := getAccessFromAnnotations(svc.Annotations) + ep = append(ep, endpointsByAccessType(access, externalIPs, internalIPs)...) } else { ep = append(ep, address.IP) log.Debugf("Generating matching endpoint %s with EndpointAddress IP %s", headlessDomain, ep) @@ -626,16 +625,20 @@ func (sc *serviceSource) extractNodePortTargets(svc *v1.Service) (endpoint.Targe } access := getAccessFromAnnotations(svc.Annotations) + return endpointsByAccessType(access, externalIPs, internalIPs), nil +} + +func endpointsByAccessType(access string, externalIPs endpoint.Targets, internalIPs endpoint.Targets) endpoint.Targets { if access == "public" { - return externalIPs, nil + return externalIPs } if access == "private" { - return internalIPs, nil + return internalIPs } if len(externalIPs) > 0 { - return externalIPs, nil + return externalIPs } - return internalIPs, nil + return internalIPs } func (sc *serviceSource) extractNodePortEndpoints(svc *v1.Service, nodeTargets endpoint.Targets, hostname string, ttl endpoint.TTL) []*endpoint.Endpoint { diff --git a/source/service_test.go b/source/service_test.go index 7ebf37ecaf..39af94779a 100644 --- a/source/service_test.go +++ b/source/service_test.go @@ -2627,10 +2627,23 @@ func TestHeadlessServicesHostIP(t *testing.T) { var addresses []v1.EndpointAddress var notReadyAddresses []v1.EndpointAddress for i, podname := range tc.podnames { + node := &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node-" + podname, + }, + Spec: v1.NodeSpec{}, + Status: v1.NodeStatus{ + Addresses: []v1.NodeAddress{}, + }, + } + _, err = kubernetes.CoreV1().Nodes().Create(context.TODO(), node, metav1.CreateOptions{}) + require.NoError(t, err) + pod := &v1.Pod{ Spec: v1.PodSpec{ Containers: []v1.Container{}, Hostname: tc.hostnames[i], + NodeName: node.Name, }, ObjectMeta: metav1.ObjectMeta{ Namespace: tc.svcNamespace, @@ -2740,8 +2753,8 @@ func TestHeadlessServicesExternalHostIP(t *testing.T) { false, map[string]string{"component": "foo"}, map[string]string{ - externalIPAnnotationKey: "", - hostnameAnnotationKey: "service.example.org", + accessAnnotationKey: "public", + hostnameAnnotationKey: "service.example.org", }, v1.ClusterIPNone, []string{"1.1.1.1", "1.1.1.2"}, @@ -2771,8 +2784,8 @@ func TestHeadlessServicesExternalHostIP(t *testing.T) { true, map[string]string{"component": "foo"}, map[string]string{ - externalIPAnnotationKey: "", - hostnameAnnotationKey: "service.example.org", + accessAnnotationKey: "public", + hostnameAnnotationKey: "service.example.org", }, v1.ClusterIPNone, []string{"1.1.1.1", "1.1.1.2"}, @@ -2798,9 +2811,9 @@ func TestHeadlessServicesExternalHostIP(t *testing.T) { false, map[string]string{"component": "foo"}, map[string]string{ - externalIPAnnotationKey: "", - hostnameAnnotationKey: "service.example.org", - ttlAnnotationKey: "1", + accessAnnotationKey: "public", + hostnameAnnotationKey: "service.example.org", + ttlAnnotationKey: "1", }, v1.ClusterIPNone, []string{"1.1.1.1", "1.1.1.2"}, @@ -2830,8 +2843,8 @@ func TestHeadlessServicesExternalHostIP(t *testing.T) { false, map[string]string{"component": "foo"}, map[string]string{ - externalIPAnnotationKey: "", - hostnameAnnotationKey: "service.example.org", + accessAnnotationKey: "public", + hostnameAnnotationKey: "service.example.org", }, v1.ClusterIPNone, []string{"1.1.1.1", "1.1.1.2"}, @@ -2860,8 +2873,8 @@ func TestHeadlessServicesExternalHostIP(t *testing.T) { false, map[string]string{"component": "foo"}, map[string]string{ - externalIPAnnotationKey: "", - hostnameAnnotationKey: "service.example.org", + accessAnnotationKey: "public", + hostnameAnnotationKey: "service.example.org", }, v1.ClusterIPNone, []string{"1.1.1.1", "1.1.1.2"}, diff --git a/source/source.go b/source/source.go index 770b026ca4..069ee47535 100644 --- a/source/source.go +++ b/source/source.go @@ -46,8 +46,6 @@ const ( ttlAnnotationKey = "external-dns.alpha.kubernetes.io/ttl" // The annotation used for switching to the alias record types e. g. AWS Alias records instead of a normal CNAME aliasAnnotationKey = "external-dns.alpha.kubernetes.io/alias" - // The annotation used for having publishHostIP use the ExternalIP of the Host Node - externalIPAnnotationKey = "external-dns.alpha.kubernetes.io/use-external-host-ip" // The value of the controller annotation so that we feel responsible controllerAnnotationValue = "dns-controller" // The annotation used for defining the desired hostname