From c4898b7e980035c3978876f5d434ca61b58715de Mon Sep 17 00:00:00 2001 From: Dave Salisbury Date: Sun, 18 Apr 2021 14:13:53 +1000 Subject: [PATCH] Plumb in filtering on ingress class name --- main.go | 1 + pkg/apis/externaldns/types.go | 3 +++ source/ingress.go | 32 +++++++++++++++++++++++++++++++- source/store.go | 3 ++- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index 5843a583f..b10c3372a 100644 --- a/main.go +++ b/main.go @@ -104,6 +104,7 @@ func main() { Namespace: cfg.Namespace, AnnotationFilter: cfg.AnnotationFilter, LabelFilter: cfg.LabelFilter, + IngressClassNameFilter: cfg.IngressClassNameFilter, FQDNTemplate: cfg.FQDNTemplate, CombineFQDNAndAnnotation: cfg.CombineFQDNAndAnnotation, IgnoreHostnameAnnotation: cfg.IgnoreHostnameAnnotation, diff --git a/pkg/apis/externaldns/types.go b/pkg/apis/externaldns/types.go index 89e053b86..e9153ab7c 100644 --- a/pkg/apis/externaldns/types.go +++ b/pkg/apis/externaldns/types.go @@ -53,6 +53,7 @@ type Config struct { Namespace string AnnotationFilter string LabelFilter string + IngressClassNameFilter []string FQDNTemplate string CombineFQDNAndAnnotation bool IgnoreHostnameAnnotation bool @@ -186,6 +187,7 @@ var defaultConfig = &Config{ Namespace: "", AnnotationFilter: "", LabelFilter: "", + IngressClassNameFilter: nil, FQDNTemplate: "", CombineFQDNAndAnnotation: false, IgnoreHostnameAnnotation: false, @@ -362,6 +364,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("ingress-class-filter", "Filter ingresses to just these ingress class(es)").StringsVar(&cfg.IngressClassNameFilter) 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) diff --git a/source/ingress.go b/source/ingress.go index e81f524d1..01b987300 100644 --- a/source/ingress.go +++ b/source/ingress.go @@ -54,6 +54,7 @@ type ingressSource struct { client kubernetes.Interface namespace string annotationFilter string + ingressClassNameFilter []string fqdnTemplate *template.Template combineFQDNAnnotation bool ignoreHostnameAnnotation bool @@ -63,7 +64,7 @@ type ingressSource struct { } // NewIngressSource creates a new ingressSource with the given config. -func NewIngressSource(kubeClient kubernetes.Interface, namespace, annotationFilter string, fqdnTemplate string, combineFqdnAnnotation bool, ignoreHostnameAnnotation bool, ignoreIngressTLSSpec bool, ignoreIngressRulesSpec bool) (Source, error) { +func NewIngressSource(kubeClient kubernetes.Interface, namespace, annotationFilter string, fqdnTemplate string, combineFqdnAnnotation bool, ignoreHostnameAnnotation bool, ignoreIngressTLSSpec bool, ignoreIngressRulesSpec bool, ingressClassNameFilter []string) (Source, error) { tmpl, err := parseTemplate(fqdnTemplate) if err != nil { return nil, err @@ -94,6 +95,7 @@ func NewIngressSource(kubeClient kubernetes.Interface, namespace, annotationFilt client: kubeClient, namespace: namespace, annotationFilter: annotationFilter, + ingressClassNameFilter: ingressClassNameFilter, fqdnTemplate: tmpl, combineFQDNAnnotation: combineFqdnAnnotation, ignoreHostnameAnnotation: ignoreHostnameAnnotation, @@ -116,6 +118,11 @@ func (sc *ingressSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e return nil, err } + ingresses, err = sc.filterByIngressClass(ingresses) + if err != nil { + return nil, err + } + endpoints := []*endpoint.Endpoint{} for _, ing := range ingresses { @@ -210,6 +217,29 @@ func (sc *ingressSource) filterByAnnotations(ingresses []*networkv1.Ingress) ([] return filteredList, nil } +// filterByIngressClass filters a list of ingresses based on a required ingress +// class +func (sc *ingressSource) filterByIngressClass(ingresses []*v1beta1.Ingress) ([]*v1beta1.Ingress, error) { + // if no class is specified then there's nothing to do + if sc.ingressClassNameFilter == nil { + return ingresses, nil + } + + filteredList := []*v1beta1.Ingress{} + + for _, ingress := range ingresses { + for _, nameFilter := range sc.ingressClassNameFilter { + // include ingress if its annotations match the selector + if ingress.Spec.IngressClassName != nil && nameFilter == *ingress.Spec.IngressClassName { + filteredList = append(filteredList, ingress) + break + } + } + } + + return filteredList, nil +} + func (sc *ingressSource) setResourceLabel(ingress *networkv1.Ingress, endpoints []*endpoint.Endpoint) { for _, ep := range endpoints { ep.Labels[endpoint.ResourceLabelKey] = fmt.Sprintf("ingress/%s/%s", ingress.Namespace, ingress.Name) diff --git a/source/store.go b/source/store.go index 3b8372255..5cb2d47bf 100644 --- a/source/store.go +++ b/source/store.go @@ -43,6 +43,7 @@ type Config struct { Namespace string AnnotationFilter string LabelFilter string + IngressClassNameFilter []string FQDNTemplate string CombineFQDNAndAnnotation bool IgnoreHostnameAnnotation bool @@ -189,7 +190,7 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err if err != nil { return nil, err } - return NewIngressSource(client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation, cfg.IgnoreIngressTLSSpec, cfg.IgnoreIngressRulesSpec) + return NewIngressSource(client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation, cfg.IgnoreIngressTLSSpec, cfg.IgnoreIngressRulesSpec, cfg.IngressClassNameFilter) case "pod": client, err := p.KubeClient() if err != nil {