diff --git a/provider/pihole/clientV6_test.go b/provider/pihole/clientV6_test.go index 697571792..ba1403821 100644 --- a/provider/pihole/clientV6_test.go +++ b/provider/pihole/clientV6_test.go @@ -61,7 +61,7 @@ func TestIsValidIPv6(t *testing.T) { }{ {"2001:0db8:85a3:0000:0000:8a2e:0370:7334", true}, {"2001:db8:85a3::8a2e:370:7334", true}, - //IPV6 dual, the format is y:y:y:y:y:y:x.x.x.x. + //IPv6 dual, the format is y:y:y:y:y:y:x.x.x.x. {"::ffff:192.168.20.3", true}, {"::1", true}, {"::", true}, diff --git a/source/compatibility.go b/source/compatibility.go index 373daba0f..fc54552f5 100644 --- a/source/compatibility.go +++ b/source/compatibility.go @@ -159,7 +159,7 @@ func legacyEndpointsFromDNSControllerNodePortService(svc *v1.Service, sc *servic for _, address := range node.Status.Addresses { recordType := suitableType(address.Address) // IPv6 addresses are labeled as NodeInternalIP despite being usable externally as well. - if isExternal && (address.Type == v1.NodeExternalIP || (address.Type == v1.NodeInternalIP && recordType == endpoint.RecordTypeAAAA)) { + if isExternal && (address.Type == v1.NodeExternalIP || (sc.exposeInternalIPv6 && address.Type == v1.NodeInternalIP && recordType == endpoint.RecordTypeAAAA)) { endpoints = append(endpoints, endpoint.NewEndpoint(hostname, recordType, address.Address)) } if isInternal && address.Type == v1.NodeInternalIP { diff --git a/source/node.go b/source/node.go index 055cd38a0..3f76e6655 100644 --- a/source/node.go +++ b/source/node.go @@ -43,7 +43,7 @@ type nodeSource struct { nodeInformer coreinformers.NodeInformer labelSelector labels.Selector excludeUnschedulable bool - exposeInternalIPV6 bool + exposeInternalIPv6 bool } // NewNodeSource creates a new nodeSource with the given config. @@ -81,7 +81,7 @@ func NewNodeSource(ctx context.Context, kubeClient kubernetes.Interface, annotat nodeInformer: nodeInformer, labelSelector: labelSelector, excludeUnschedulable: excludeUnschedulable, - exposeInternalIPV6: exposeInternalIPv6, + exposeInternalIPv6: exposeInternalIPv6, }, nil } @@ -193,7 +193,7 @@ func (ns *nodeSource) nodeAddresses(node *v1.Node) ([]string, error) { } if len(addresses[v1.NodeExternalIP]) > 0 { - if ns.exposeInternalIPV6 { + if ns.exposeInternalIPv6 { log.Warn(warningMsg) return append(addresses[v1.NodeExternalIP], internalIpv6Addresses...), nil } diff --git a/source/service.go b/source/service.go index 2c33dceac..c341d3f85 100644 --- a/source/service.go +++ b/source/service.go @@ -65,10 +65,11 @@ type serviceSource struct { nodeInformer coreinformers.NodeInformer serviceTypeFilter map[string]struct{} labelSelector labels.Selector + exposeInternalIPv6 bool } // NewServiceSource creates a new serviceSource with the given config. -func NewServiceSource(ctx context.Context, kubeClient kubernetes.Interface, namespace, annotationFilter, fqdnTemplate string, combineFqdnAnnotation bool, compatibility string, publishInternal, publishHostIP, alwaysPublishNotReadyAddresses bool, serviceTypeFilter []string, ignoreHostnameAnnotation bool, labelSelector labels.Selector, resolveLoadBalancerHostname, listenEndpointEvents bool) (Source, error) { +func NewServiceSource(ctx context.Context, kubeClient kubernetes.Interface, namespace, annotationFilter, fqdnTemplate string, combineFqdnAnnotation bool, compatibility string, publishInternal, publishHostIP, alwaysPublishNotReadyAddresses bool, serviceTypeFilter []string, ignoreHostnameAnnotation bool, labelSelector labels.Selector, resolveLoadBalancerHostname, listenEndpointEvents bool, exposeInternalIPv6 bool) (Source, error) { tmpl, err := fqdn.ParseTemplate(fqdnTemplate) if err != nil { return nil, err @@ -141,6 +142,7 @@ func NewServiceSource(ctx context.Context, kubeClient kubernetes.Interface, name labelSelector: labelSelector, resolveLoadBalancerHostname: resolveLoadBalancerHostname, listenEndpointEvents: listenEndpointEvents, + exposeInternalIPv6: exposeInternalIPv6, }, nil } @@ -319,7 +321,7 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri return endpoints } for _, address := range node.Status.Addresses { - if address.Type == v1.NodeExternalIP || (address.Type == v1.NodeInternalIP && suitableType(address.Address) == endpoint.RecordTypeAAAA) { + if address.Type == v1.NodeExternalIP || (sc.exposeInternalIPv6 && address.Type == v1.NodeInternalIP && suitableType(address.Address) == endpoint.RecordTypeAAAA) { targets = append(targets, address.Address) log.Debugf("Generating matching endpoint %s with NodeExternalIP %s", headlessDomain, address.Address) } diff --git a/source/service_test.go b/source/service_test.go index 5e9948abe..1eaebfe56 100644 --- a/source/service_test.go +++ b/source/service_test.go @@ -82,6 +82,7 @@ func (suite *ServiceSuite) SetupTest() { labels.Everything(), false, false, + false, ) suite.NoError(err, "should initialize service source") } @@ -164,6 +165,7 @@ func testServiceSourceNewServiceSource(t *testing.T) { labels.Everything(), false, false, + false, ) if ti.expectError { @@ -1136,6 +1138,7 @@ func testServiceSourceEndpoints(t *testing.T) { sourceLabel, tc.resolveLoadBalancerHostname, false, + false, ) require.NoError(t, err) @@ -1351,6 +1354,7 @@ func testMultipleServicesEndpoints(t *testing.T) { labels.Everything(), false, false, + false, ) require.NoError(t, err) @@ -1655,6 +1659,7 @@ func TestClusterIpServices(t *testing.T) { labelSelector, false, false, + false, ) require.NoError(t, err) @@ -1686,6 +1691,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { compatibility string fqdnTemplate string ignoreHostnameAnnotation bool + exposeInternalIPv6 bool labels map[string]string annotations map[string]string lbs []string @@ -2207,12 +2213,13 @@ func TestServiceSourceNodePortServices(t *testing.T) { }}, }, { - title: "node port services annotated with external DNS Controller annotations return an endpoint in compatibility mode", - svcNamespace: "testing", - svcName: "foo", - svcType: v1.ServiceTypeNodePort, - svcTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeCluster, - compatibility: "kops-dns-controller", + title: "node port services annotated with external DNS Controller annotations return an endpoint in compatibility mode with exposeInternalIPv6 flag set", + svcNamespace: "testing", + svcName: "foo", + svcType: v1.ServiceTypeNodePort, + svcTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeCluster, + compatibility: "kops-dns-controller", + exposeInternalIPv6: true, annotations: map[string]string{ kopsDNSControllerHostnameAnnotationKey: "foo.example.org., bar.example.org", }, @@ -2374,6 +2381,7 @@ func TestServiceSourceNodePortServices(t *testing.T) { labels.Everything(), false, false, + tc.exposeInternalIPv6, ) require.NoError(t, err) @@ -2403,6 +2411,7 @@ func TestHeadlessServices(t *testing.T) { compatibility string fqdnTemplate string ignoreHostnameAnnotation bool + exposeInternalIPv6 bool labels map[string]string svcAnnotations map[string]string podAnnotations map[string]string @@ -2428,6 +2437,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2461,6 +2471,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2494,6 +2505,7 @@ func TestHeadlessServices(t *testing.T) { "", "", true, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2523,6 +2535,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2557,6 +2570,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2591,6 +2605,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2623,6 +2638,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2656,6 +2672,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2687,6 +2704,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2718,6 +2736,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2749,6 +2768,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2782,6 +2802,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2815,6 +2836,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2850,7 +2872,7 @@ func TestHeadlessServices(t *testing.T) { false, }, { - "annotated Headless services return IPv6 targets from node external IP if endpoints-type annotation is set", + "annotated Headless services return only external IPv6 targets from node IP if endpoints-type annotation is set and exposeInternalIPv6 flag is unset", "", "testing", "foo", @@ -2858,6 +2880,55 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, + map[string]string{"component": "foo"}, + map[string]string{ + hostnameAnnotationKey: "service.example.org", + endpointsTypeAnnotationKey: EndpointsTypeNodeExternalIP, + }, + map[string]string{}, + v1.ClusterIPNone, + []string{"2001:db8::1"}, + []string{""}, + map[string]string{ + "component": "foo", + }, + []string{}, + []string{"foo"}, + []string{"", "", ""}, + []bool{true, true, true}, + false, + []v1.Node{ + { + Status: v1.NodeStatus{ + Addresses: []v1.NodeAddress{ + { + Type: v1.NodeInternalIP, + Address: "2001:db8::4", + }, + { + Type: v1.NodeExternalIP, + Address: "2001:db8::5", + }, + }, + }, + }, + }, + []*endpoint.Endpoint{ + {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::5"}}, + }, + false, + }, + { + "annotated Headless services return IPv6 targets from node external IP if endpoints-type annotation is set and exposeInternalIPv6 flag set", + "", + "testing", + "foo", + v1.ServiceTypeClusterIP, + "", + "", + false, + true, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2893,7 +2964,7 @@ func TestHeadlessServices(t *testing.T) { false, }, { - "annotated Headless services return dual-stack targets from node external IP if endpoints-type annotation is set", + "annotated Headless services return dual-stack targets from node external IP if endpoints-type annotation is set and exposeInternalIPv6 flag set", "", "testing", "foo", @@ -2901,6 +2972,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + true, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2949,6 +3021,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -2981,6 +3054,7 @@ func TestHeadlessServices(t *testing.T) { "", "", false, + false, map[string]string{"component": "foo"}, map[string]string{ hostnameAnnotationKey: "service.example.org", @@ -3103,6 +3177,7 @@ func TestHeadlessServices(t *testing.T) { labels.Everything(), false, false, + tc.exposeInternalIPv6, ) require.NoError(t, err) @@ -3563,6 +3638,7 @@ func TestHeadlessServicesHostIP(t *testing.T) { labels.Everything(), false, false, + false, ) require.NoError(t, err) @@ -3742,6 +3818,7 @@ func TestExternalServices(t *testing.T) { labels.Everything(), false, false, + false, ) require.NoError(t, err) @@ -3798,6 +3875,7 @@ func BenchmarkServiceEndpoints(b *testing.B) { labels.Everything(), false, false, + false, ) require.NoError(b, err) diff --git a/source/store.go b/source/store.go index 8a9149ba5..f8ef39b58 100644 --- a/source/store.go +++ b/source/store.go @@ -273,7 +273,7 @@ func BuildWithConfig(ctx context.Context, source string, p ClientGenerator, cfg if err != nil { return nil, err } - return NewServiceSource(ctx, client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.Compatibility, cfg.PublishInternal, cfg.PublishHostIP, cfg.AlwaysPublishNotReadyAddresses, cfg.ServiceTypeFilter, cfg.IgnoreHostnameAnnotation, cfg.LabelFilter, cfg.ResolveLoadBalancerHostname, cfg.ListenEndpointEvents) + return NewServiceSource(ctx, client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.Compatibility, cfg.PublishInternal, cfg.PublishHostIP, cfg.AlwaysPublishNotReadyAddresses, cfg.ServiceTypeFilter, cfg.IgnoreHostnameAnnotation, cfg.LabelFilter, cfg.ResolveLoadBalancerHostname, cfg.ListenEndpointEvents, cfg.ExposeInternalIPv6) case "ingress": client, err := p.KubeClient() if err != nil {