mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 09:36:58 +02:00
Added labelFilter for source CRD (#1461)
* Added label filter for source CRD * Fixed bug with labels and added tests for source CRD * Fixed formating * Update source/crd_test.go Co-authored-by: Vinny Sabatini <vincent.sabatini@gmail.com> Co-authored-by: Vinny Sabatini <vincent.sabatini@gmail.com>
This commit is contained in:
parent
32fedeaf07
commit
79ea64884b
1
main.go
1
main.go
@ -100,6 +100,7 @@ func main() {
|
||||
sourceCfg := &source.Config{
|
||||
Namespace: cfg.Namespace,
|
||||
AnnotationFilter: cfg.AnnotationFilter,
|
||||
LabelFilter: cfg.LabelFilter,
|
||||
FQDNTemplate: cfg.FQDNTemplate,
|
||||
CombineFQDNAndAnnotation: cfg.CombineFQDNAndAnnotation,
|
||||
IgnoreHostnameAnnotation: cfg.IgnoreHostnameAnnotation,
|
||||
|
@ -47,6 +47,7 @@ type Config struct {
|
||||
Sources []string
|
||||
Namespace string
|
||||
AnnotationFilter string
|
||||
LabelFilter string
|
||||
FQDNTemplate string
|
||||
CombineFQDNAndAnnotation bool
|
||||
IgnoreHostnameAnnotation bool
|
||||
@ -157,6 +158,7 @@ var defaultConfig = &Config{
|
||||
Sources: nil,
|
||||
Namespace: "",
|
||||
AnnotationFilter: "",
|
||||
LabelFilter: "",
|
||||
FQDNTemplate: "",
|
||||
CombineFQDNAndAnnotation: false,
|
||||
IgnoreHostnameAnnotation: false,
|
||||
@ -310,6 +312,7 @@ func (cfg *Config) ParseFlags(args []string) error {
|
||||
|
||||
app.Flag("namespace", "Limit sources of endpoints to a specific namespace (default: all namespaces)").Default(defaultConfig.Namespace).StringVar(&cfg.Namespace)
|
||||
app.Flag("annotation-filter", "Filter sources managed by external-dns via annotation using label selector semantics (default: all sources)").Default(defaultConfig.AnnotationFilter).StringVar(&cfg.AnnotationFilter)
|
||||
app.Flag("label-filter", "Filter sources managed by external-dns via label selector when listing all resources; currently only supported by source CRD").Default(defaultConfig.LabelFilter).StringVar(&cfg.LabelFilter)
|
||||
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("ignore-hostname-annotation", "Ignore hostname annotation when generating DNS names, valid only when using fqdn-template is set (optional, default: false)").BoolVar(&cfg.IgnoreHostnameAnnotation)
|
||||
|
@ -43,6 +43,7 @@ type crdSource struct {
|
||||
crdResource string
|
||||
codec runtime.ParameterCodec
|
||||
annotationFilter string
|
||||
labelFilter string
|
||||
}
|
||||
|
||||
func addKnownTypes(scheme *runtime.Scheme, groupVersion schema.GroupVersion) error {
|
||||
@ -102,11 +103,12 @@ func NewCRDClientForAPIVersionKind(client kubernetes.Interface, kubeConfig, apiS
|
||||
}
|
||||
|
||||
// NewCRDSource creates a new crdSource with the given config.
|
||||
func NewCRDSource(crdClient rest.Interface, namespace, kind string, annotationFilter string, scheme *runtime.Scheme) (Source, error) {
|
||||
func NewCRDSource(crdClient rest.Interface, namespace, kind string, annotationFilter string, labelFilter string, scheme *runtime.Scheme) (Source, error) {
|
||||
return &crdSource{
|
||||
crdResource: strings.ToLower(kind) + "s",
|
||||
namespace: namespace,
|
||||
annotationFilter: annotationFilter,
|
||||
labelFilter: labelFilter,
|
||||
crdClient: crdClient,
|
||||
codec: runtime.NewParameterCodec(scheme),
|
||||
}, nil
|
||||
@ -119,12 +121,22 @@ func (cs *crdSource) AddEventHandler(ctx context.Context, handler func()) {
|
||||
func (cs *crdSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) {
|
||||
endpoints := []*endpoint.Endpoint{}
|
||||
|
||||
result, err := cs.List(ctx, &metav1.ListOptions{})
|
||||
var (
|
||||
result *endpoint.DNSEndpointList
|
||||
err error
|
||||
)
|
||||
|
||||
if cs.labelFilter != "" {
|
||||
result, err = cs.List(ctx, &metav1.ListOptions{LabelSelector: cs.labelFilter})
|
||||
} else {
|
||||
result, err = cs.List(ctx, &metav1.ListOptions{})
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err = cs.filterByAnnotations(result)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ func objBody(codec runtime.Encoder, obj runtime.Object) io.ReadCloser {
|
||||
return ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(codec, obj))))
|
||||
}
|
||||
|
||||
func startCRDServerToServeTargets(endpoints []*endpoint.Endpoint, apiVersion, kind, namespace, name string, annotations map[string]string, t *testing.T) rest.Interface {
|
||||
func startCRDServerToServeTargets(endpoints []*endpoint.Endpoint, apiVersion, kind, namespace, name string, annotations map[string]string, labels map[string]string, t *testing.T) rest.Interface {
|
||||
groupVersion, _ := schema.ParseGroupVersion(apiVersion)
|
||||
scheme := runtime.NewScheme()
|
||||
addKnownTypes(scheme, groupVersion)
|
||||
@ -72,6 +72,7 @@ func startCRDServerToServeTargets(endpoints []*endpoint.Endpoint, apiVersion, ki
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
Annotations: annotations,
|
||||
Labels: labels,
|
||||
Generation: 1,
|
||||
},
|
||||
Spec: endpoint.DNSEndpointSpec{
|
||||
@ -139,7 +140,9 @@ func testCRDSourceEndpoints(t *testing.T) {
|
||||
expectEndpoints bool
|
||||
expectError bool
|
||||
annotationFilter string
|
||||
labelFilter string
|
||||
annotations map[string]string
|
||||
labels map[string]string
|
||||
}{
|
||||
{
|
||||
title: "invalid crd api version",
|
||||
@ -308,16 +311,56 @@ func testCRDSourceEndpoints(t *testing.T) {
|
||||
expectEndpoints: true,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
title: "valid crd gvk with label and non matching label filter",
|
||||
registeredAPIVersion: "test.k8s.io/v1alpha1",
|
||||
apiVersion: "test.k8s.io/v1alpha1",
|
||||
registeredKind: "DNSEndpoint",
|
||||
kind: "DNSEndpoint",
|
||||
namespace: "foo",
|
||||
registeredNamespace: "foo",
|
||||
labels: map[string]string{"test": "that"},
|
||||
labelFilter: "test=filter_something_else",
|
||||
endpoints: []*endpoint.Endpoint{
|
||||
{DNSName: "abc.example.org",
|
||||
Targets: endpoint.Targets{"1.2.3.4"},
|
||||
RecordType: endpoint.RecordTypeA,
|
||||
RecordTTL: 180,
|
||||
},
|
||||
},
|
||||
expectEndpoints: false,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
title: "valid crd gvk with label and matching label filter",
|
||||
registeredAPIVersion: "test.k8s.io/v1alpha1",
|
||||
apiVersion: "test.k8s.io/v1alpha1",
|
||||
registeredKind: "DNSEndpoint",
|
||||
kind: "DNSEndpoint",
|
||||
namespace: "foo",
|
||||
registeredNamespace: "foo",
|
||||
labels: map[string]string{"test": "that"},
|
||||
labelFilter: "test=that",
|
||||
endpoints: []*endpoint.Endpoint{
|
||||
{DNSName: "abc.example.org",
|
||||
Targets: endpoint.Targets{"1.2.3.4"},
|
||||
RecordType: endpoint.RecordTypeA,
|
||||
RecordTTL: 180,
|
||||
},
|
||||
},
|
||||
expectEndpoints: true,
|
||||
expectError: false,
|
||||
},
|
||||
} {
|
||||
t.Run(ti.title, func(t *testing.T) {
|
||||
restClient := startCRDServerToServeTargets(ti.endpoints, ti.registeredAPIVersion, ti.registeredKind, ti.registeredNamespace, "test", ti.annotations, t)
|
||||
restClient := startCRDServerToServeTargets(ti.endpoints, ti.registeredAPIVersion, ti.registeredKind, ti.registeredNamespace, "test", ti.annotations, ti.labels, t)
|
||||
groupVersion, err := schema.ParseGroupVersion(ti.apiVersion)
|
||||
require.NoError(t, err)
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
addKnownTypes(scheme, groupVersion)
|
||||
|
||||
cs, _ := NewCRDSource(restClient, ti.namespace, ti.kind, ti.annotationFilter, scheme)
|
||||
cs, _ := NewCRDSource(restClient, ti.namespace, ti.kind, ti.annotationFilter, ti.labelFilter, scheme)
|
||||
|
||||
receivedEndpoints, err := cs.Endpoints(context.Background())
|
||||
if ti.expectError {
|
||||
|
@ -42,6 +42,7 @@ var ErrSourceNotFound = errors.New("source not found")
|
||||
type Config struct {
|
||||
Namespace string
|
||||
AnnotationFilter string
|
||||
LabelFilter string
|
||||
FQDNTemplate string
|
||||
CombineFQDNAndAnnotation bool
|
||||
IgnoreHostnameAnnotation bool
|
||||
@ -247,7 +248,7 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewCRDSource(crdClient, cfg.Namespace, cfg.CRDSourceKind, cfg.AnnotationFilter, scheme)
|
||||
return NewCRDSource(crdClient, cfg.Namespace, cfg.CRDSourceKind, cfg.AnnotationFilter, cfg.LabelFilter, scheme)
|
||||
case "skipper-routegroup":
|
||||
apiServerURL := cfg.APIServerURL
|
||||
tokenPath := ""
|
||||
|
Loading…
Reference in New Issue
Block a user