mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 09:36:58 +02:00
Support --label-filter for node source
This commit is contained in:
parent
ed78d02793
commit
75639b759c
@ -18,7 +18,7 @@
|
|||||||
| istio-gateway | Gateway.networking.istio.io | Yes | |
|
| istio-gateway | Gateway.networking.istio.io | Yes | |
|
||||||
| istio-virtualservice | VirtualService.networking.istio.io | Yes | |
|
| istio-virtualservice | VirtualService.networking.istio.io | Yes | |
|
||||||
| kong-tcpingress | TCPIngress.configuration.konghq.com | Yes | |
|
| kong-tcpingress | TCPIngress.configuration.konghq.com | Yes | |
|
||||||
| node | Node | Yes | |
|
| node | Node | Yes | Yes |
|
||||||
| openshift-route | Route.route.openshift.io | Yes | Yes |
|
| openshift-route | Route.route.openshift.io | Yes | Yes |
|
||||||
| pod | Pod | | |
|
| pod | Pod | | |
|
||||||
| [service](service.md) | Service | Yes | Yes |
|
| [service](service.md) | Service | Yes | Yes |
|
||||||
|
@ -422,7 +422,7 @@ func (cfg *Config) ParseFlags(args []string) error {
|
|||||||
app.Flag("openshift-router-name", "if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record.").StringVar(&cfg.OCPRouterName)
|
app.Flag("openshift-router-name", "if source is openshift-route then you can pass the ingress controller name. Based on this name external-dns will select the respective router from the route status and map that routerCanonicalHostname to the route host while creating a CNAME record.").StringVar(&cfg.OCPRouterName)
|
||||||
app.Flag("namespace", "Limit resources queried for endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace)
|
app.Flag("namespace", "Limit resources queried for endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace)
|
||||||
app.Flag("annotation-filter", "Filter resources queried for endpoints by annotation, using label selector semantics").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter)
|
app.Flag("annotation-filter", "Filter resources queried for endpoints by annotation, using label selector semantics").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter)
|
||||||
app.Flag("label-filter", "Filter resources queried for endpoints by label selector; currently supported by source types crd, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, ingress, openshift-route, and service").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter)
|
app.Flag("label-filter", "Filter resources queried for endpoints by label selector; currently supported by source types crd, gateway-httproute, gateway-grpcroute, gateway-tlsroute, gateway-tcproute, gateway-udproute, ingress, node, openshift-route, and service").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter)
|
||||||
app.Flag("ingress-class", "Require an Ingress to have this class name (defaults to any class; specify multiple times to allow more than one class)").StringsVar(&cfg.IngressClassNames)
|
app.Flag("ingress-class", "Require an Ingress to have this class name (defaults to any class; specify multiple times to allow more than one class)").StringsVar(&cfg.IngressClassNames)
|
||||||
app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate)
|
app.Flag("fqdn-template", "A templated string that's used to generate DNS names from sources that don't define a hostname themselves, or to add a hostname suffix when paired with the fake source (optional). Accepts comma separated list for multiple global FQDN.").Default(defaultConfig.FQDNTemplate).StringVar(&cfg.FQDNTemplate)
|
||||||
app.Flag("combine-fqdn-annotation", "Combine FQDN template and Annotations instead of overwriting").BoolVar(&cfg.CombineFQDNAndAnnotation)
|
app.Flag("combine-fqdn-annotation", "Combine FQDN template and Annotations instead of overwriting").BoolVar(&cfg.CombineFQDNAndAnnotation)
|
||||||
|
@ -38,10 +38,11 @@ type nodeSource struct {
|
|||||||
annotationFilter string
|
annotationFilter string
|
||||||
fqdnTemplate *template.Template
|
fqdnTemplate *template.Template
|
||||||
nodeInformer coreinformers.NodeInformer
|
nodeInformer coreinformers.NodeInformer
|
||||||
|
labelSelector labels.Selector
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNodeSource creates a new nodeSource with the given config.
|
// NewNodeSource creates a new nodeSource with the given config.
|
||||||
func NewNodeSource(ctx context.Context, kubeClient kubernetes.Interface, annotationFilter, fqdnTemplate string) (Source, error) {
|
func NewNodeSource(ctx context.Context, kubeClient kubernetes.Interface, annotationFilter, fqdnTemplate string, labelSelector labels.Selector) (Source, error) {
|
||||||
tmpl, err := parseTemplate(fqdnTemplate)
|
tmpl, err := parseTemplate(fqdnTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -73,12 +74,13 @@ func NewNodeSource(ctx context.Context, kubeClient kubernetes.Interface, annotat
|
|||||||
annotationFilter: annotationFilter,
|
annotationFilter: annotationFilter,
|
||||||
fqdnTemplate: tmpl,
|
fqdnTemplate: tmpl,
|
||||||
nodeInformer: nodeInformer,
|
nodeInformer: nodeInformer,
|
||||||
|
labelSelector: labelSelector,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Endpoints returns endpoint objects for each service that should be processed.
|
// Endpoints returns endpoint objects for each service that should be processed.
|
||||||
func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) {
|
func (ns *nodeSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) {
|
||||||
nodes, err := ns.nodeInformer.Lister().List(labels.Everything())
|
nodes, err := ns.nodeInformer.Lister().List(ns.labelSelector)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
|
|
||||||
"sigs.k8s.io/external-dns/endpoint"
|
"sigs.k8s.io/external-dns/endpoint"
|
||||||
@ -75,6 +76,7 @@ func testNodeSourceNewNodeSource(t *testing.T) {
|
|||||||
fake.NewSimpleClientset(),
|
fake.NewSimpleClientset(),
|
||||||
ti.annotationFilter,
|
ti.annotationFilter,
|
||||||
ti.fqdnTemplate,
|
ti.fqdnTemplate,
|
||||||
|
labels.Everything(),
|
||||||
)
|
)
|
||||||
|
|
||||||
if ti.expectError {
|
if ti.expectError {
|
||||||
@ -93,6 +95,7 @@ func testNodeSourceEndpoints(t *testing.T) {
|
|||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
title string
|
title string
|
||||||
annotationFilter string
|
annotationFilter string
|
||||||
|
labelSelector string
|
||||||
fqdnTemplate string
|
fqdnTemplate string
|
||||||
nodeName string
|
nodeName string
|
||||||
nodeAddresses []v1.NodeAddress
|
nodeAddresses []v1.NodeAddress
|
||||||
@ -102,294 +105,223 @@ func testNodeSourceEndpoints(t *testing.T) {
|
|||||||
expectError bool
|
expectError bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"node with short hostname returns one endpoint",
|
title: "node with short hostname returns one endpoint",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
"node1",
|
expected: []*endpoint.Endpoint{
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"node with fqdn returns one endpoint",
|
title: "node with fqdn returns one endpoint",
|
||||||
"",
|
nodeName: "node1.example.org",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
"node1.example.org",
|
expected: []*endpoint.Endpoint{
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
|
{RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ipv6 node with fqdn returns one endpoint",
|
title: "ipv6 node with fqdn returns one endpoint",
|
||||||
"",
|
nodeName: "node1.example.org",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "2001:DB8::8"}},
|
||||||
"node1.example.org",
|
expected: []*endpoint.Endpoint{
|
||||||
[]v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "2001:DB8::8"}},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "AAAA", DNSName: "node1.example.org", Targets: endpoint.Targets{"2001:DB8::8"}},
|
{RecordType: "AAAA", DNSName: "node1.example.org", Targets: endpoint.Targets{"2001:DB8::8"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"node with fqdn template returns endpoint with expanded hostname",
|
title: "node with fqdn template returns endpoint with expanded hostname",
|
||||||
"",
|
fqdnTemplate: "{{.Name}}.example.org",
|
||||||
"{{.Name}}.example.org",
|
nodeName: "node1",
|
||||||
"node1",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
expected: []*endpoint.Endpoint{
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
|
{RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"node with fqdn and fqdn template returns one endpoint",
|
title: "node with fqdn and fqdn template returns one endpoint",
|
||||||
"",
|
fqdnTemplate: "{{.Name}}.example.org",
|
||||||
"{{.Name}}.example.org",
|
nodeName: "node1.example.org",
|
||||||
"node1.example.org",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
expected: []*endpoint.Endpoint{
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1.example.org.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
|
{RecordType: "A", DNSName: "node1.example.org.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"node with fqdn template returns two endpoints with multiple IP addresses and expanded hostname",
|
title: "node with fqdn template returns two endpoints with multiple IP addresses and expanded hostname",
|
||||||
"",
|
fqdnTemplate: "{{.Name}}.example.org",
|
||||||
"{{.Name}}.example.org",
|
nodeName: "node1",
|
||||||
"node1",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeExternalIP, Address: "5.6.7.8"}},
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeExternalIP, Address: "5.6.7.8"}},
|
expected: []*endpoint.Endpoint{
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4", "5.6.7.8"}},
|
{RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4", "5.6.7.8"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"node with fqdn template returns two endpoints with dual-stack IP addresses and expanded hostname",
|
title: "node with fqdn template returns two endpoints with dual-stack IP addresses and expanded hostname",
|
||||||
"",
|
fqdnTemplate: "{{.Name}}.example.org",
|
||||||
"{{.Name}}.example.org",
|
nodeName: "node1",
|
||||||
"node1",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2001:DB8::8"}},
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2001:DB8::8"}},
|
expected: []*endpoint.Endpoint{
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
|
{RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||||
{RecordType: "AAAA", DNSName: "node1.example.org", Targets: endpoint.Targets{"2001:DB8::8"}},
|
{RecordType: "AAAA", DNSName: "node1.example.org", Targets: endpoint.Targets{"2001:DB8::8"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"node with both external and internal IP returns an endpoint with external IP",
|
title: "node with both external and internal IP returns an endpoint with external IP",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2.3.4.5"}},
|
||||||
"node1",
|
expected: []*endpoint.Endpoint{
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2.3.4.5"}},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"node with both external, internal, and IPv6 IP returns endpoints with external IPs",
|
title: "node with both external, internal, and IPv6 IP returns endpoints with external IPs",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2.3.4.5"}, {Type: v1.NodeInternalIP, Address: "2001:DB8::8"}},
|
||||||
"node1",
|
expected: []*endpoint.Endpoint{
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2.3.4.5"}, {Type: v1.NodeInternalIP, Address: "2001:DB8::8"}},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||||
{RecordType: "AAAA", DNSName: "node1", Targets: endpoint.Targets{"2001:DB8::8"}},
|
{RecordType: "AAAA", DNSName: "node1", Targets: endpoint.Targets{"2001:DB8::8"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"node with only internal IP returns an endpoint with internal IP",
|
title: "node with only internal IP returns an endpoint with internal IP",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "2.3.4.5"}},
|
||||||
"node1",
|
expected: []*endpoint.Endpoint{
|
||||||
[]v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "2.3.4.5"}},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"2.3.4.5"}},
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"2.3.4.5"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"node with only internal IPs returns endpoints with internal IPs",
|
title: "node with only internal IPs returns endpoints with internal IPs",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "2.3.4.5"}, {Type: v1.NodeInternalIP, Address: "2001:DB8::8"}},
|
||||||
"node1",
|
expected: []*endpoint.Endpoint{
|
||||||
[]v1.NodeAddress{{Type: v1.NodeInternalIP, Address: "2.3.4.5"}, {Type: v1.NodeInternalIP, Address: "2001:DB8::8"}},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"2.3.4.5"}},
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"2.3.4.5"}},
|
||||||
{RecordType: "AAAA", DNSName: "node1", Targets: endpoint.Targets{"2001:DB8::8"}},
|
{RecordType: "AAAA", DNSName: "node1", Targets: endpoint.Targets{"2001:DB8::8"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"node with neither external nor internal IP returns no endpoints",
|
title: "node with neither external nor internal IP returns no endpoints",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{},
|
||||||
"node1",
|
expectError: true,
|
||||||
[]v1.NodeAddress{},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{},
|
|
||||||
true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"annotated node without annotation filter returns endpoint",
|
title: "annotated node without annotation filter returns endpoint",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
"node1",
|
annotations: map[string]string{
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{
|
|
||||||
"service.beta.kubernetes.io/external-traffic": "OnlyLocal",
|
"service.beta.kubernetes.io/external-traffic": "OnlyLocal",
|
||||||
},
|
},
|
||||||
[]*endpoint.Endpoint{
|
expected: []*endpoint.Endpoint{
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"annotated node with matching annotation filter returns endpoint",
|
title: "annotated node with matching annotation filter returns endpoint",
|
||||||
"service.beta.kubernetes.io/external-traffic in (Global, OnlyLocal)",
|
annotationFilter: "service.beta.kubernetes.io/external-traffic in (Global, OnlyLocal)",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"node1",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
annotations: map[string]string{
|
||||||
map[string]string{},
|
|
||||||
map[string]string{
|
|
||||||
"service.beta.kubernetes.io/external-traffic": "OnlyLocal",
|
"service.beta.kubernetes.io/external-traffic": "OnlyLocal",
|
||||||
},
|
},
|
||||||
[]*endpoint.Endpoint{
|
expected: []*endpoint.Endpoint{
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"annotated node with non-matching annotation filter returns endpoint",
|
title: "annotated node with non-matching annotation filter returns nothing",
|
||||||
"service.beta.kubernetes.io/external-traffic in (Global, OnlyLocal)",
|
annotationFilter: "service.beta.kubernetes.io/external-traffic in (Global, OnlyLocal)",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"node1",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
annotations: map[string]string{
|
||||||
map[string]string{},
|
|
||||||
map[string]string{
|
|
||||||
"service.beta.kubernetes.io/external-traffic": "SomethingElse",
|
"service.beta.kubernetes.io/external-traffic": "SomethingElse",
|
||||||
},
|
},
|
||||||
[]*endpoint.Endpoint{},
|
expected: []*endpoint.Endpoint{},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"our controller type is dns-controller",
|
title: "labeled node with matching label selector returns endpoint",
|
||||||
"",
|
labelSelector: "service.beta.kubernetes.io/external-traffic in (Global, OnlyLocal)",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"node1",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
labels: map[string]string{
|
||||||
map[string]string{},
|
"service.beta.kubernetes.io/external-traffic": "OnlyLocal",
|
||||||
map[string]string{
|
|
||||||
controllerAnnotationKey: controllerAnnotationValue,
|
|
||||||
},
|
},
|
||||||
[]*endpoint.Endpoint{
|
expected: []*endpoint.Endpoint{
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"different controller types are ignored",
|
title: "labeled node with non-matching label selector returns nothing",
|
||||||
"",
|
labelSelector: "service.beta.kubernetes.io/external-traffic in (Global, OnlyLocal)",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"node1",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
labels: map[string]string{
|
||||||
map[string]string{},
|
"service.beta.kubernetes.io/external-traffic": "SomethingElse",
|
||||||
map[string]string{
|
},
|
||||||
|
expected: []*endpoint.Endpoint{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "our controller type is dns-controller",
|
||||||
|
nodeName: "node1",
|
||||||
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
|
annotations: map[string]string{
|
||||||
|
controllerAnnotationKey: controllerAnnotationValue,
|
||||||
|
},
|
||||||
|
expected: []*endpoint.Endpoint{
|
||||||
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "different controller types are ignored",
|
||||||
|
nodeName: "node1",
|
||||||
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
|
annotations: map[string]string{
|
||||||
controllerAnnotationKey: "not-dns-controller",
|
controllerAnnotationKey: "not-dns-controller",
|
||||||
},
|
},
|
||||||
[]*endpoint.Endpoint{},
|
expected: []*endpoint.Endpoint{},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ttl not annotated should have RecordTTL.IsConfigured set to false",
|
title: "ttl not annotated should have RecordTTL.IsConfigured set to false",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
"node1",
|
expected: []*endpoint.Endpoint{
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)},
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ttl annotated but invalid should have RecordTTL.IsConfigured set to false",
|
title: "ttl annotated but invalid should have RecordTTL.IsConfigured set to false",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
"node1",
|
annotations: map[string]string{
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{
|
|
||||||
ttlAnnotationKey: "foo",
|
ttlAnnotationKey: "foo",
|
||||||
},
|
},
|
||||||
[]*endpoint.Endpoint{
|
expected: []*endpoint.Endpoint{
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)},
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ttl annotated and is valid should set Record.TTL",
|
title: "ttl annotated and is valid should set Record.TTL",
|
||||||
"",
|
nodeName: "node1",
|
||||||
"",
|
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
||||||
"node1",
|
annotations: map[string]string{
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
|
||||||
map[string]string{},
|
|
||||||
map[string]string{
|
|
||||||
ttlAnnotationKey: "10",
|
ttlAnnotationKey: "10",
|
||||||
},
|
},
|
||||||
[]*endpoint.Endpoint{
|
expected: []*endpoint.Endpoint{
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(10)},
|
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(10)},
|
||||||
},
|
},
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"node with nil Labels returns valid endpoint",
|
|
||||||
"",
|
|
||||||
"",
|
|
||||||
"node1",
|
|
||||||
[]v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}},
|
|
||||||
nil,
|
|
||||||
map[string]string{},
|
|
||||||
[]*endpoint.Endpoint{
|
|
||||||
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}, Labels: map[string]string{}},
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
tc := tc
|
tc := tc
|
||||||
t.Run(tc.title, func(t *testing.T) {
|
t.Run(tc.title, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
labelSelector := labels.Everything()
|
||||||
|
if tc.labelSelector != "" {
|
||||||
|
var err error
|
||||||
|
labelSelector, err = labels.Parse(tc.labelSelector)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
// Create a Kubernetes testing client
|
// Create a Kubernetes testing client
|
||||||
kubernetes := fake.NewSimpleClientset()
|
kubernetes := fake.NewSimpleClientset()
|
||||||
|
|
||||||
@ -413,6 +345,7 @@ func testNodeSourceEndpoints(t *testing.T) {
|
|||||||
kubernetes,
|
kubernetes,
|
||||||
tc.annotationFilter,
|
tc.annotationFilter,
|
||||||
tc.fqdnTemplate,
|
tc.fqdnTemplate,
|
||||||
|
labelSelector,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ func BuildWithConfig(ctx context.Context, source string, p ClientGenerator, cfg
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return NewNodeSource(ctx, client, cfg.AnnotationFilter, cfg.FQDNTemplate)
|
return NewNodeSource(ctx, client, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.LabelFilter)
|
||||||
case "service":
|
case "service":
|
||||||
client, err := p.KubeClient()
|
client, err := p.KubeClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user