-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow filtering by source annotation #354
allow filtering by source annotation #354
Conversation
@khrisrichardson Thanks for your contribution. I would like to avoid tying ExternalDNS to a specific annotation that's used by another project. However, these two projects are related to each other so I'm not opposed to the idea. Though, we could solve the issue more generic by allowing people to filter Ingresses (and Services etc.) by arbitrary annotation selectors. This way people could invoke ExternalDNS with: $ ./external-dns --source=Ingress --source-annotation-filter=kubernetes.io/ingress.class=foo --provider=... This would allow people to run ExternalDNS on a subset of Ingresses for any reason and wouldn't tie us to the particular We did the same thing in I see, though, that Let me know what you think. |
Hi @linki. I had similar reservations about using a filter on an annotation outside the project's scope. I think we can make this generic pretty easily. |
main.go
Outdated
FQDNTemplate: cfg.FQDNTemplate, | ||
Compatibility: cfg.Compatibility, | ||
PublishInternal: cfg.PublishInternal, | ||
SourceAnnotationFilter: cfg.SourceAnnotationFilter, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's omit the Source
prefix because we're already using the Config
from the source package.
pkg/apis/externaldns/types.go
Outdated
LogFormat string | ||
MetricsAddress string | ||
LogLevel string | ||
SourceAnnotationFilter string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to maintain a cosistent ordering. Let's add this under/behind the source's namespace
parameter. So, in all the structs, tests and kingpin definitionions.
pkg/apis/externaldns/types.go
Outdated
@@ -139,6 +141,7 @@ func (cfg *Config) ParseFlags(args []string) error { | |||
app.Flag("log-format", "The format in which log messages are printed (default: text, options: text, json)").Default(defaultConfig.LogFormat).EnumVar(&cfg.LogFormat, "text", "json") | |||
app.Flag("metrics-address", "Specify where to serve the metrics and health check endpoint (default: :7979)").Default(defaultConfig.MetricsAddress).StringVar(&cfg.MetricsAddress) | |||
app.Flag("log-level", "Set the level of logging. (default: info, options: panic, debug, info, warn, error, fatal").Default(defaultConfig.LogLevel).EnumVar(&cfg.LogLevel, allLogLevelsAsStrings()...) | |||
app.Flag("source-annotation-filter", "Filter sources managed by external-dns via annotation regexp pattern (default: all sources)").Default(defaultConfig.SourceAnnotationFilter).StringVar(&cfg.SourceAnnotationFilter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just use --annotation-filter
. It currently fits better with --namespace
which is also a filter on the source side. I think we won't have annotation filtering stuff on the provider side for a while.
source/ingress.go
Outdated
log.Debugf("Skipping ingress %s/%s because '%s' annotation does not match pattern, found: %s, expected: %s", | ||
ing.Namespace, ing.Name, annotation, string, pattern) | ||
continue | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recommend adopting this pattern: https://github.com/linki/chaoskube/blob/v0.6.0/chaoskube/chaoskube.go#L180-L199
With this you get all the matching functionality from Kubernetes itself for free, including matching multiple labels, checking for existence (--filter=foo
) as well as exclusion (--filter=ingress.class!=nginx
).
@linki, are there any other changes you would propose following my latest updates. Do you think we should rename annotationFilter to annotationSelector? |
source/ingress.go
Outdated
@@ -70,6 +73,10 @@ func (sc *ingressSource) Endpoints() ([]*endpoint.Endpoint, error) { | |||
if err != nil { | |||
return nil, err | |||
} | |||
ingresses.Items, err = sc.filterByAnnotations(ingresses.Items, sc.annotationFilter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you call a method of "sc", you should not pass sc.annotationFilter as parameter, but use it in the method from your receiver.
source/service.go
Outdated
@@ -75,6 +78,10 @@ func (sc *serviceSource) Endpoints() ([]*endpoint.Endpoint, error) { | |||
if err != nil { | |||
return nil, err | |||
} | |||
services.Items, err = sc.filterByAnnotations(services.Items, sc.annotationFilter) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here is the same case, passing sc.annotationFilter to a function receiver of sc.
source/service.go
Outdated
@@ -148,6 +155,37 @@ func (sc *serviceSource) endpoints(svc *v1.Service) []*endpoint.Endpoint { | |||
return endpoints | |||
} | |||
|
|||
// filterByAnnotations filters a list of services by a given annotation selector. | |||
func (sc *serviceSource) filterByAnnotations(services []v1.Service, annotationFilter string) ([]v1.Service, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there was no case to pass the filter as parameter, because it's already member of serviceSource.
For me this looks good. Only a tiny nitpick and we can merge it. |
…ternal-dns into ingress-class-pattern
LGTM 👍 Thanks @khrisrichardson and @szuecs for the implementation and reviews. |
Should we merge? Any reason not to? |
please merge @hjacobs , I just don't have the right to do so |
@ideahitme can you merge this please? |
* allow filtering by ingress class * generic source annotation filter as opposed to ingress class filter * rename and fix argument ordering, switch to label selector semantics * remove redundant parameters
In certain scenarios, there may be multiple ingress controllers running in the same Kubernetes cluster with different ingress classes (e.g. - ALB + Tectonic ingress), and it would be desirable to toggle which controllers' resources had their DNS records managed by external-dns. The intention of this PR is to manage that scenario via pattern matching on the ingress class annotation:
kubernetes.io/ingress.class
.