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 1.5 support #327

Closed
wants to merge 14 commits into from
Closed

Marathon 1.5 support #327

wants to merge 14 commits into from

Conversation

kamsz
Copy link
Contributor

@kamsz kamsz commented Oct 24, 2017

Tested very briefly so far, mostly with terraform-provider-marathon.

@gambol99
Copy link
Owner

gambol99 commented Nov 2, 2017

hi @kamsz ... apologizes for the delay, i'm gonna try look at this one day ..

@gambol99 gambol99 self-assigned this Nov 2, 2017
@kamsz
Copy link
Contributor Author

kamsz commented Nov 3, 2017

@gambol99 no prob, I'm using it heavily with terraform-provider-marathon and so far it works without issues.

Copy link
Collaborator

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

AFAICS, the PR breaks backwards compatibility for clients that are not on Marathon 1.5 and haven't adjusted to the API changes yet. I think we should try hard to make the new features additive without removing the old functionality right away.

WDYT?

application.go Outdated
@@ -34,14 +34,6 @@ type Applications struct {
Apps []Application `json:"apps"`
}

// IPAddressPerTask is used by IP-per-task functionality https://mesosphere.github.io/marathon/docs/ip-per-task.html
type IPAddressPerTask struct {
Copy link
Collaborator

Choose a reason for hiding this comment

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

IP address per task seems to be removed. Is it because Marathon 1.5 does not support it anymore?

We should try hard not to break existing clients if somehow possible.

application.go Outdated
@@ -54,6 +46,12 @@ type Port struct {
Protocol string `json:"protocol,omitempty"`
}

// Network providers info about application networking
Copy link
Collaborator

Choose a reason for hiding this comment

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

Typo: provides.

application.go Outdated
@@ -72,7 +72,6 @@ type Application struct {
Instances *int `json:"instances,omitempty"`
Mem *float64 `json:"mem,omitempty"`
Tasks []*Task `json:"tasks,omitempty"`
Ports []int `json:"ports"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Will removing this field break backwards compatibility?

application.go Outdated
@@ -92,14 +91,12 @@ type Application struct {
UpgradeStrategy *UpgradeStrategy `json:"upgradeStrategy,omitempty"`
UnreachableStrategy *UnreachableStrategy `json:"unreachableStrategy,omitempty"`
KillSelection string `json:"killSelection,omitempty"`
Uris *[]string `json:"uris,omitempty"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Will removing this field break backwards compatibility?

application.go Outdated
@@ -493,7 +479,7 @@ func (r *Application) CheckHTTP(path string, port, interval int) (*Application,
return nil, ErrNoApplicationContainer
}
// step: get the port index
portIndex, err := r.Container.Docker.ServicePortIndex(port)
portIndex, err := r.Container.ServicePortIndex(port)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Backwards compatibility?

application.go Outdated
}

// HostNetwork sets the networking mode to host
func (r *Application) HostNetwork(name string) *Application {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of having three different methods to set the network mode, let's have a single one that takes a custom string type denoting the possible modes (which we can provide from a set of constants).

@timoreimann
Copy link
Collaborator

Hey there @kamsz, do you possibly have any news?

@kamsz
Copy link
Contributor Author

kamsz commented Nov 16, 2017

@timoreimann Hi, not yet. I didn't have time to work on that this week. I'll try to look into this next week.

@kamsz
Copy link
Contributor Author

kamsz commented Nov 23, 2017

@timoreimann I've tried my best to keep backward compatibility. I'll try to fix tests tomorrow. Could you please look at the changes and let me know what you think?

@kamsz
Copy link
Contributor Author

kamsz commented Nov 24, 2017

I've fixed some tests. Not sure how to fix a group test, since methods from methods.yml would collide. Any ideas? @timoreimann @gambol99

Copy link
Collaborator

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

I haven't been able to complete the review yet. Nevertheless, I wanted to leave notes on two major points that caught my attention: Using table-driven tests and dropping the Container part from new method names. Let me know what you think.

I'll also look into the group testing question you had. Maybe our Marathon fake framework can help with that, but I yet have to dig deeper to say for sure.

Thanks for all your work on getting go-marathon ready for 1.5! 👏 I'll get back to you as soon as I can.

@@ -42,6 +42,32 @@ func TestApplicationMemory(t *testing.T) {
assert.Equal(t, 50.0, *app.Mem)
}

func TestNewApplicationString(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you please try to merge this test with TestApplicationString in a table-driven fashion like we also do it here?

I think the test struct should come with a func(app *Application) that does the version-specific modifications, and another string specifying the golden test data to compare against.

Please also try to do so for the other newly created tests that are similar enough to existing tests.

docker.go Outdated
// port: the port you are looking for
func (container *Container) ContainerServicePortIndex(port int) (int, error) {
if container.PortMappings == nil || len(*container.PortMappings) == 0 {
return 0, errors.New("The docker does not contain any port mappings to search")
Copy link
Collaborator

Choose a reason for hiding this comment

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

The docker sounds wrong -- should probably be The container.

docker.go Outdated
}

// step: we didn't find the port in the mappings
return 0, fmt.Errorf("The container port required was not found in the container port mappings")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's mention the container port we intend to find.

docker.go Outdated
@@ -255,6 +257,19 @@ func (docker *Docker) Host() *Docker {
return docker
}

// ExposeContainer sets the container to expose the following TCP ports
// ports: the TCP ports the container is exposing
func (container *Container) ExposeContainer(ports ...int) *Container {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think we should have the Container part in the ExposeContainer method name: The method is already defined on a Container, so users should be able to infer the type easily (and we can't conflict).

I'm also thinking it could make it easier for people to transition from Marathon pre-v1.5 to v1.5+ if most method names stay the same. We might even reuse part of the logic. WDYT?

(Similar argumentation for other new methods also coming with a Container name part.)

@kamsz
Copy link
Contributor Author

kamsz commented Nov 27, 2017

@timoreimann I've fixed most of the comments you had. Still not sure what to do with this group test.

Copy link
Collaborator

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

I left a note on the first test in the PR and would love to see my suggestions be applied there and in the other tests. Basically, I'd like us to use table-driven tests where the setup is part of each test case (i.e., defined in the fields of the associated anonymous struct).

Regarding group tests: Do I understand correctly that you'd like the tests to return a different result from a particular endpoint than what's already specified in the YAML file today? If so, then I think scopes could solve your problem. Have you taken a look at that? Would it help?

I actually have a question on the group matter: In your PR I see group-related tests being amended but no production code getting added. Does that mean we have some kind of breaking change on the groups endpoint? Or did I miss something?

// Marathon >= 1.5
tests[1].app.
Container.Expose(80).Expose(443).
Docker.Container("quay.io/gambol99/apache-php:latest")
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it'd be better to extend each test struct by a func(*Application) function which encapsulates the version-specific setup logic. That way, we are able to maintain all setup functionality inside tests.

Same for the other tests you have adapted.

Container.Expose(80).Expose(443).
Docker.Container("quay.io/gambol99/apache-php:latest")

for i := range tests {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd reference the value in the loop and access the necessary fields directly.


for i := range tests {
_, err := tests[i].app.CheckHTTP("/health", 80, 5)
assert.Nil(t, err)
Copy link
Collaborator

Choose a reason for hiding this comment

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

We need a name/label here (set up like this) so that we can distinguish which test case actually fail.

Similar for the other assertions.

@katallaxie
Copy link

@kamsz are you still working on that? Or should I catch up? Because I would really love to see this in Traefik 1.5

@timoreimann
Copy link
Collaborator

@katallaxie from my perspective, I believe it's okay to carry the PR at this stage. Bringing the feature to completion would make a lot of folks quite happy. :)

@katallaxie katallaxie mentioned this pull request Jan 28, 2018
@kamsz kamsz closed this Feb 3, 2021
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.

4 participants