-
Notifications
You must be signed in to change notification settings - Fork 5.1k
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
Marathon constraints filtering #2388
Conversation
e2cfb14
to
2e29778
Compare
2e29778
to
2e632a0
Compare
@timoreimann WDYT ? |
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.
The feature definitely makes sense to me since Marathon constraints are a very canonical way to filter with this provider.
I left a few comments.
provider/marathon/marathon.go
Outdated
@@ -59,6 +59,7 @@ type Provider struct { | |||
GroupsAsSubDomains bool `description:"Convert Marathon groups to subdomains" export:"true"` | |||
DCOSToken string `description:"DCOSToken for DCOS environment, This will override the Authorization header" export:"true"` | |||
MarathonLBCompatibility bool `description:"Add compatibility with marathon-lb labels" export:"true"` | |||
MarathonConstraints bool `description:"Enable use of Marathon constraints in constraint filtering" export:"true"` |
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.
Since this is a boolean flag, can we have a verb-ish prefix? How about something like filterMarathonConstraints
?
provider/marathon/marathon.go
Outdated
@@ -247,6 +248,13 @@ func (p *Provider) applicationFilter(app marathon.Application) bool { | |||
constraintTags = append(constraintTags, label) | |||
} | |||
} | |||
if p.MarathonConstraints { | |||
if app.Constraints != nil && len(*app.Constraints) > 0 { |
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 believe we can drop the right-hand expression and merge the left-hand one with the previous line like this:
if p.MarathonConstraints && app.Constraints != nil {
for _, list := range *app.Constraints {
provider/marathon/marathon_test.go
Outdated
desc: "constraint valid", | ||
application: application(constraint("valid")), | ||
marathonLBCompatibility: false, | ||
marathonConstraints: true, |
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.
Can we group by Nevermind actually, it doesn't make sense here.expected
outcome, going with false
first?
@@ -68,6 +68,13 @@ domain = "marathon.localhost" | |||
# | |||
# marathonLBCompatibility = true | |||
|
|||
# Enable marathon constraints. |
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 we should elaborate just a bit what "enable" means (i.e., that we parse Marathon constraints and treat the compound constraint parts as a single tag to match literally).
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.
Done
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.
Shall we phrase this as Enable filtering by Marathon constraints.?
@@ -44,6 +44,12 @@ func label(key, value string) func(*marathon.Application) { | |||
} | |||
} | |||
|
|||
func constraint(value string) func(*marathon.Application) { |
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.
Looking at the function signature, it might not be immediately clear to the caller that colons must be used as separators. I know it's only a few lines below, but how about making the function variadic at the second parameter (i.e., constraint(value1 string, values... string) func(*marathon.Application)
) to increase clarity?
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 was really trying to keep it as a single string, as in the Marathon config (not using the json API), it is defined as a single string with 3 components, separated with a :
. Even the Marathon UI uses just a single text field to add the constrain labels, so I'd rather keep this aligned, to be consistent.
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.
That's a reasonable argument. Let's keep a single string then.
provider/marathon/marathon.go
Outdated
@@ -247,6 +248,13 @@ func (p *Provider) applicationFilter(app marathon.Application) bool { | |||
constraintTags = append(constraintTags, label) | |||
} | |||
} | |||
if p.MarathonConstraints { | |||
if app.Constraints != nil && len(*app.Constraints) > 0 { | |||
for _, list := range *app.Constraints { |
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.
Can we rename list
to constraintParts
? That's also how the official documentation calls them.
provider/marathon/marathon_test.go
Outdated
expected bool | ||
}{ | ||
{ | ||
desc: "tags missing", | ||
application: application(), | ||
marathonLBCompatibility: false, | ||
marathonConstraints: false, |
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.
Should we omit marathonConstraint
(and possibly other parameters) when they are not needed / relevant for a test?
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.
Some small bits left.
@@ -68,6 +68,13 @@ domain = "marathon.localhost" | |||
# | |||
# marathonLBCompatibility = true | |||
|
|||
# Enable marathon constraints. |
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.
Shall we phrase this as Enable filtering by Marathon constraints.?
@@ -68,6 +68,16 @@ domain = "marathon.localhost" | |||
# | |||
# marathonLBCompatibility = true | |||
|
|||
# Enable marathon constraints. | |||
# If enabled, Traefik will read Marathon constrains, as defined in https://mesosphere.github.io/marathon/docs/constraints.html |
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.
Typo: constraints
@@ -68,6 +68,16 @@ domain = "marathon.localhost" | |||
# | |||
# marathonLBCompatibility = true | |||
|
|||
# Enable marathon constraints. | |||
# If enabled, Traefik will read Marathon constrains, as defined in https://mesosphere.github.io/marathon/docs/constraints.html | |||
# Each individual constraint will be treated as a verbatum compounded tag. |
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.
Typo: verbatim
# Optional | ||
# Default: false | ||
# | ||
# marathonConstraints = true |
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.
We need to update the name
provider/marathon/marathon.go
Outdated
@@ -247,6 +248,11 @@ func (p *Provider) applicationFilter(app marathon.Application) bool { | |||
constraintTags = append(constraintTags, label) | |||
} | |||
} | |||
if p.FilterMarathonConstraints && app.Constraints != nil && len(*app.Constraints) > 0 { |
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.
We can omit the last expression on the constraint length.
provider/marathon/marathon_test.go
Outdated
@@ -522,6 +522,7 @@ func TestMarathonApplicationFilterConstraints(t *testing.T) { | |||
desc string | |||
application marathon.Application | |||
marathonLBCompatibility bool | |||
marathonConstraints bool |
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 prepend this by filter too to match the real flag name.
04539de
to
4946c6f
Compare
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.
LGTM -- thanks, Alex. 👏
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.
LGTM
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.
LGTM
4946c6f
to
bc4a411
Compare
What does this PR do?
Add support for filtering based on Marathon-defined constraints, as described in https://mesosphere.github.io/marathon/docs/constraints.html
Motivation
Many Marathon clusters have applications deployed with various "constraints", configuring things like application service affinity, cluster binding, etc. It would be very helpful to not have to add additional/duplicate
traefik.tags
labels to the applications and to be able to filter using already defined Marathon constraints instead.More