Skip to content
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

Merged
merged 3 commits into from
Nov 21, 2017
Merged

Conversation

aantono
Copy link
Contributor

@aantono aantono commented Nov 10, 2017

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

  • Added/updated tests
  • Added/updated documentation

@ldez
Copy link
Contributor

ldez commented Nov 16, 2017

@timoreimann WDYT ?

Copy link
Contributor

@timoreimann timoreimann left a 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.

@@ -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"`
Copy link
Contributor

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?

@@ -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 {
Copy link
Contributor

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 {

desc: "constraint valid",
application: application(constraint("valid")),
marathonLBCompatibility: false,
marathonConstraints: true,
Copy link
Contributor

@timoreimann timoreimann Nov 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we group by expected outcome, going with false first? Nevermind actually, it doesn't make sense here.

@@ -68,6 +68,13 @@ domain = "marathon.localhost"
#
# marathonLBCompatibility = true

# Enable marathon constraints.
Copy link
Contributor

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).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

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) {
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

@@ -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 {
Copy link
Contributor

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.

expected bool
}{
{
desc: "tags missing",
application: application(),
marathonLBCompatibility: false,
marathonConstraints: false,
Copy link
Contributor

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?

Copy link
Contributor

@timoreimann timoreimann left a 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.
Copy link
Contributor

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
Copy link
Contributor

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.
Copy link
Contributor

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
Copy link
Contributor

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

@@ -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 {
Copy link
Contributor

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.

@@ -522,6 +522,7 @@ func TestMarathonApplicationFilterConstraints(t *testing.T) {
desc string
application marathon.Application
marathonLBCompatibility bool
marathonConstraints bool
Copy link
Contributor

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.

Copy link
Contributor

@timoreimann timoreimann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM -- thanks, Alex. 👏

Copy link
Member

@juliens juliens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ldez ldez added this to the 1.5 milestone Nov 21, 2017
Copy link
Contributor

@ldez ldez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants