Upgrade go-marathon to 15ea23e.

Our vendored copy contains a bug that causes unavailable Marathon nodes
to never be marked as available again due to a misconstruction in the
URL to the Marathon health check / ping endpoint used by go-marathon
internally.

A fix[1] has been published.

[1]https://github.com/gambol99/go-marathon/pull/283
This commit is contained in:
Timo Reimann 2017-05-19 14:24:28 +02:00
parent 2e762e76f3
commit 219a6372b0
10 changed files with 126 additions and 72 deletions

4
glide.lock generated
View file

@ -1,5 +1,5 @@
hash: 1aa32496b865dda72d76c7cba3458f1c2c467acf0b99aab4609323f109aa64f6 hash: 1aa32496b865dda72d76c7cba3458f1c2c467acf0b99aab4609323f109aa64f6
updated: 2017-05-02T11:46:23.91434995-04:00 updated: 2017-05-19T23:30:19.890844996+02:00
imports: imports:
- name: cloud.google.com/go - name: cloud.google.com/go
version: 2e6a95edb1071d750f6d7db777bf66cd2997af6c version: 2e6a95edb1071d750f6d7db777bf66cd2997af6c
@ -201,7 +201,7 @@ imports:
- name: github.com/fatih/color - name: github.com/fatih/color
version: 9131ab34cf20d2f6d83fdc67168a5430d1c7dc23 version: 9131ab34cf20d2f6d83fdc67168a5430d1c7dc23
- name: github.com/gambol99/go-marathon - name: github.com/gambol99/go-marathon
version: d672c6fbb499596869d95146a26e7d0746c06c54 version: 15ea23e360abb8b25071e677aed344f31838e403
- name: github.com/ghodss/yaml - name: github.com/ghodss/yaml
version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee
- name: github.com/go-ini/ini - name: github.com/go-ini/ini

View file

@ -89,6 +89,8 @@ type Application struct {
TaskStats map[string]TaskStats `json:"taskStats,omitempty"` TaskStats map[string]TaskStats `json:"taskStats,omitempty"`
User string `json:"user,omitempty"` User string `json:"user,omitempty"`
UpgradeStrategy *UpgradeStrategy `json:"upgradeStrategy,omitempty"` UpgradeStrategy *UpgradeStrategy `json:"upgradeStrategy,omitempty"`
UnreachableStrategy *UnreachableStrategy `json:"unreachableStrategy,omitempty"`
KillSelection string `json:"killSelection,omitempty"`
Uris *[]string `json:"uris,omitempty"` Uris *[]string `json:"uris,omitempty"`
Version string `json:"version,omitempty"` Version string `json:"version,omitempty"`
VersionInfo *VersionInfo `json:"versionInfo,omitempty"` VersionInfo *VersionInfo `json:"versionInfo,omitempty"`
@ -453,7 +455,7 @@ func (r *Application) DeploymentIDs() []*DeploymentID {
// CheckHTTP adds a HTTP check to an application // CheckHTTP adds a HTTP check to an application
// port: the port the check should be checking // port: the port the check should be checking
// interval: the interval in seconds the check should be performed // interval: the interval in seconds the check should be performed
func (r *Application) CheckHTTP(uri string, port, interval int) (*Application, error) { func (r *Application) CheckHTTP(path string, port, interval int) (*Application, error) {
if r.Container == nil || r.Container.Docker == nil { if r.Container == nil || r.Container.Docker == nil {
return nil, ErrNoApplicationContainer return nil, ErrNoApplicationContainer
} }
@ -464,7 +466,7 @@ func (r *Application) CheckHTTP(uri string, port, interval int) (*Application, e
} }
health := NewDefaultHealthCheck() health := NewDefaultHealthCheck()
health.IntervalSeconds = interval health.IntervalSeconds = interval
*health.Path = uri *health.Path = path
*health.PortIndex = portIndex *health.PortIndex = portIndex
// step: add to the checks // step: add to the checks
r.AddHealthCheck(*health) r.AddHealthCheck(*health)
@ -555,6 +557,20 @@ func (r *Application) EmptyUpgradeStrategy() *Application {
return r return r
} }
// SetUnreachableStrategy sets the unreachable strategy.
func (r *Application) SetUnreachableStrategy(us UnreachableStrategy) *Application {
r.UnreachableStrategy = &us
return r
}
// EmptyUnreachableStrategy explicitly empties the unreachable strategy -- use this if
// you need to empty the unreachable strategy of an application that already has
// the unreachable strategy set (setting it to nil will keep the current value).
func (r *Application) EmptyUnreachableStrategy() *Application {
r.UnreachableStrategy = &UnreachableStrategy{}
return r
}
// String returns the json representation of this application // String returns the json representation of this application
func (r *Application) String() string { func (r *Application) String() string {
s, err := json.MarshalIndent(r, "", " ") s, err := json.MarshalIndent(r, "", " ")
@ -611,9 +627,9 @@ func (r *marathonClient) HasApplicationVersion(name, version string) (bool, erro
// ApplicationVersions is a list of versions which has been deployed with marathon for a specific application // ApplicationVersions is a list of versions which has been deployed with marathon for a specific application
// name: the id used to identify the application // name: the id used to identify the application
func (r *marathonClient) ApplicationVersions(name string) (*ApplicationVersions, error) { func (r *marathonClient) ApplicationVersions(name string) (*ApplicationVersions, error) {
uri := fmt.Sprintf("%s/versions", buildURI(name)) path := fmt.Sprintf("%s/versions", buildPath(name))
versions := new(ApplicationVersions) versions := new(ApplicationVersions)
if err := r.apiGet(uri, nil, versions); err != nil { if err := r.apiGet(path, nil, versions); err != nil {
return nil, err return nil, err
} }
return versions, nil return versions, nil
@ -623,9 +639,9 @@ func (r *marathonClient) ApplicationVersions(name string) (*ApplicationVersions,
// name: the id used to identify the application // name: the id used to identify the application
// version: the version (normally a timestamp) you wish to change to // version: the version (normally a timestamp) you wish to change to
func (r *marathonClient) SetApplicationVersion(name string, version *ApplicationVersion) (*DeploymentID, error) { func (r *marathonClient) SetApplicationVersion(name string, version *ApplicationVersion) (*DeploymentID, error) {
uri := fmt.Sprintf(buildURI(name)) path := fmt.Sprintf(buildPath(name))
deploymentID := new(DeploymentID) deploymentID := new(DeploymentID)
if err := r.apiPut(uri, version, deploymentID); err != nil { if err := r.apiPut(path, version, deploymentID); err != nil {
return nil, err return nil, err
} }
@ -639,7 +655,7 @@ func (r *marathonClient) Application(name string) (*Application, error) {
Application *Application `json:"app"` Application *Application `json:"app"`
} }
if err := r.apiGet(buildURI(name), nil, &wrapper); err != nil { if err := r.apiGet(buildPath(name), nil, &wrapper); err != nil {
return nil, err return nil, err
} }
@ -650,7 +666,7 @@ func (r *marathonClient) Application(name string) (*Application, error) {
// name: the id used to identify the application // name: the id used to identify the application
// opts: GetAppOpts request payload // opts: GetAppOpts request payload
func (r *marathonClient) ApplicationBy(name string, opts *GetAppOpts) (*Application, error) { func (r *marathonClient) ApplicationBy(name string, opts *GetAppOpts) (*Application, error) {
u, err := addOptions(buildURI(name), opts) path, err := addOptions(buildPath(name), opts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -658,7 +674,7 @@ func (r *marathonClient) ApplicationBy(name string, opts *GetAppOpts) (*Applicat
Application *Application `json:"app"` Application *Application `json:"app"`
} }
if err := r.apiGet(u, nil, &wrapper); err != nil { if err := r.apiGet(path, nil, &wrapper); err != nil {
return nil, err return nil, err
} }
@ -671,8 +687,8 @@ func (r *marathonClient) ApplicationBy(name string, opts *GetAppOpts) (*Applicat
func (r *marathonClient) ApplicationByVersion(name, version string) (*Application, error) { func (r *marathonClient) ApplicationByVersion(name, version string) (*Application, error) {
app := new(Application) app := new(Application)
uri := fmt.Sprintf("%s/versions/%s", buildURI(name), version) path := fmt.Sprintf("%s/versions/%s", buildPath(name), version)
if err := r.apiGet(uri, nil, app); err != nil { if err := r.apiGet(path, nil, app); err != nil {
return nil, err return nil, err
} }
@ -779,10 +795,10 @@ func (r *marathonClient) appExistAndRunning(name string) bool {
// name: the id used to identify the application // name: the id used to identify the application
// force: used to force the delete operation in case of blocked deployment // force: used to force the delete operation in case of blocked deployment
func (r *marathonClient) DeleteApplication(name string, force bool) (*DeploymentID, error) { func (r *marathonClient) DeleteApplication(name string, force bool) (*DeploymentID, error) {
uri := buildURIWithForceParam(name, force) path := buildPathWithForceParam(name, force)
// step: check of the application already exists // step: check of the application already exists
deployID := new(DeploymentID) deployID := new(DeploymentID)
if err := r.apiDelete(uri, nil, deployID); err != nil { if err := r.apiDelete(path, nil, deployID); err != nil {
return nil, err return nil, err
} }
@ -794,8 +810,8 @@ func (r *marathonClient) DeleteApplication(name string, force bool) (*Deployment
func (r *marathonClient) RestartApplication(name string, force bool) (*DeploymentID, error) { func (r *marathonClient) RestartApplication(name string, force bool) (*DeploymentID, error) {
deployment := new(DeploymentID) deployment := new(DeploymentID)
var options struct{} var options struct{}
uri := buildURIWithForceParam(fmt.Sprintf("%s/restart", name), force) path := buildPathWithForceParam(fmt.Sprintf("%s/restart", name), force)
if err := r.apiPost(uri, &options, deployment); err != nil { if err := r.apiPost(path, &options, deployment); err != nil {
return nil, err return nil, err
} }
@ -810,9 +826,9 @@ func (r *marathonClient) ScaleApplicationInstances(name string, instances int, f
changes := new(Application) changes := new(Application)
changes.ID = validateID(name) changes.ID = validateID(name)
changes.Instances = &instances changes.Instances = &instances
uri := buildURIWithForceParam(name, force) path := buildPathWithForceParam(name, force)
deployID := new(DeploymentID) deployID := new(DeploymentID)
if err := r.apiPut(uri, changes, deployID); err != nil { if err := r.apiPut(path, changes, deployID); err != nil {
return nil, err return nil, err
} }
@ -823,22 +839,22 @@ func (r *marathonClient) ScaleApplicationInstances(name string, instances int, f
// application: the structure holding the application configuration // application: the structure holding the application configuration
func (r *marathonClient) UpdateApplication(application *Application, force bool) (*DeploymentID, error) { func (r *marathonClient) UpdateApplication(application *Application, force bool) (*DeploymentID, error) {
result := new(DeploymentID) result := new(DeploymentID)
uri := buildURIWithForceParam(application.ID, force) path := buildPathWithForceParam(application.ID, force)
if err := r.apiPut(uri, application, result); err != nil { if err := r.apiPut(path, application, result); err != nil {
return nil, err return nil, err
} }
return result, nil return result, nil
} }
func buildURIWithForceParam(path string, force bool) string { func buildPathWithForceParam(rootPath string, force bool) string {
uri := buildURI(path) path := buildPath(rootPath)
if force { if force {
uri += "?force=true" path += "?force=true"
} }
return uri return path
} }
func buildURI(path string) string { func buildPath(path string) string {
return fmt.Sprintf("%s/%s", marathonAPIApps, trimRootPath(path)) return fmt.Sprintf("%s/%s", marathonAPIApps, trimRootPath(path))
} }

View file

@ -27,6 +27,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"regexp" "regexp"
"strings"
"sync" "sync"
"time" "time"
) )
@ -238,23 +239,23 @@ func (r *marathonClient) Ping() (bool, error) {
return true, nil return true, nil
} }
func (r *marathonClient) apiGet(uri string, post, result interface{}) error { func (r *marathonClient) apiGet(path string, post, result interface{}) error {
return r.apiCall("GET", uri, post, result) return r.apiCall("GET", path, post, result)
} }
func (r *marathonClient) apiPut(uri string, post, result interface{}) error { func (r *marathonClient) apiPut(path string, post, result interface{}) error {
return r.apiCall("PUT", uri, post, result) return r.apiCall("PUT", path, post, result)
} }
func (r *marathonClient) apiPost(uri string, post, result interface{}) error { func (r *marathonClient) apiPost(path string, post, result interface{}) error {
return r.apiCall("POST", uri, post, result) return r.apiCall("POST", path, post, result)
} }
func (r *marathonClient) apiDelete(uri string, post, result interface{}) error { func (r *marathonClient) apiDelete(path string, post, result interface{}) error {
return r.apiCall("DELETE", uri, post, result) return r.apiCall("DELETE", path, post, result)
} }
func (r *marathonClient) apiCall(method, url string, body, result interface{}) error { func (r *marathonClient) apiCall(method, path string, body, result interface{}) error {
for { for {
// step: marshall the request to json // step: marshall the request to json
var requestBody []byte var requestBody []byte
@ -266,7 +267,7 @@ func (r *marathonClient) apiCall(method, url string, body, result interface{}) e
} }
// step: create the API request // step: create the API request
request, member, err := r.buildAPIRequest(method, url, bytes.NewReader(requestBody)) request, member, err := r.buildAPIRequest(method, path, bytes.NewReader(requestBody))
if err != nil { if err != nil {
return err return err
} }
@ -317,7 +318,7 @@ func (r *marathonClient) apiCall(method, url string, body, result interface{}) e
} }
// buildAPIRequest creates a default API request // buildAPIRequest creates a default API request
func (r *marathonClient) buildAPIRequest(method, uri string, reader io.Reader) (request *http.Request, member string, err error) { func (r *marathonClient) buildAPIRequest(method, path string, reader io.Reader) (request *http.Request, member string, err error) {
// Grab a member from the cluster // Grab a member from the cluster
member, err = r.hosts.getMember() member, err = r.hosts.getMember()
if err != nil { if err != nil {
@ -325,16 +326,22 @@ func (r *marathonClient) buildAPIRequest(method, uri string, reader io.Reader) (
} }
// Build the HTTP request to Marathon // Build the HTTP request to Marathon
request, err = r.client.buildMarathonRequest(method, member, uri, reader) request, err = r.client.buildMarathonRequest(method, member, path, reader)
if err != nil { if err != nil {
return nil, member, err return nil, member, err
} }
return request, member, nil return request, member, nil
} }
func (rc *httpClient) buildMarathonRequest(method string, member string, uri string, reader io.Reader) (request *http.Request, err error) { // buildMarathonRequest creates a new HTTP request and configures it according to the *httpClient configuration.
// The path must not contain a leading "/", otherwise buildMarathonRequest will panic.
func (rc *httpClient) buildMarathonRequest(method string, member string, path string, reader io.Reader) (request *http.Request, err error) {
if strings.HasPrefix(path, "/") {
panic(fmt.Sprintf("Path '%s' must not start with a leading slash", path))
}
// Create the endpoint URL // Create the endpoint URL
url := fmt.Sprintf("%s/%s", member, uri) url := fmt.Sprintf("%s/%s", member, path)
// Instantiate an HTTP request // Instantiate an HTTP request
request, err = http.NewRequest(method, url, reader) request, err = http.NewRequest(method, url, reader)

View file

@ -131,7 +131,7 @@ func (c *cluster) markDown(endpoint string) {
func (c *cluster) healthCheckNode(node *member) { func (c *cluster) healthCheckNode(node *member) {
// step: wait for the node to become active ... we are assuming a /ping is enough here // step: wait for the node to become active ... we are assuming a /ping is enough here
for { for {
req, err := c.client.buildMarathonRequest("GET", node.endpoint, "/ping", nil) req, err := c.client.buildMarathonRequest("GET", node.endpoint, "ping", nil)
if err == nil { if err == nil {
res, err := c.client.Do(req) res, err := c.client.Do(req)
if err == nil && res.StatusCode == 200 { if err == nil && res.StatusCode == 200 {

View file

@ -106,12 +106,12 @@ func (r *marathonClient) Group(name string) (*Group, error) {
// GroupsBy retrieves a list of all the groups from marathon by embed options // GroupsBy retrieves a list of all the groups from marathon by embed options
// opts: GetGroupOpts request payload // opts: GetGroupOpts request payload
func (r *marathonClient) GroupsBy(opts *GetGroupOpts) (*Groups, error) { func (r *marathonClient) GroupsBy(opts *GetGroupOpts) (*Groups, error) {
u, err := addOptions(marathonAPIGroups, opts) path, err := addOptions(marathonAPIGroups, opts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
groups := new(Groups) groups := new(Groups)
if err := r.apiGet(u, "", groups); err != nil { if err := r.apiGet(path, "", groups); err != nil {
return nil, err return nil, err
} }
return groups, nil return groups, nil
@ -121,12 +121,12 @@ func (r *marathonClient) GroupsBy(opts *GetGroupOpts) (*Groups, error) {
// name: the identifier for the group // name: the identifier for the group
// opts: GetGroupOpts request payload // opts: GetGroupOpts request payload
func (r *marathonClient) GroupBy(name string, opts *GetGroupOpts) (*Group, error) { func (r *marathonClient) GroupBy(name string, opts *GetGroupOpts) (*Group, error) {
u, err := addOptions(fmt.Sprintf("%s/%s", marathonAPIGroups, trimRootPath(name)), opts) path, err := addOptions(fmt.Sprintf("%s/%s", marathonAPIGroups, trimRootPath(name)), opts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
group := new(Group) group := new(Group)
if err := r.apiGet(u, nil, group); err != nil { if err := r.apiGet(path, nil, group); err != nil {
return nil, err return nil, err
} }
return group, nil return group, nil
@ -135,8 +135,8 @@ func (r *marathonClient) GroupBy(name string, opts *GetGroupOpts) (*Group, error
// HasGroup checks if the group exists in marathon // HasGroup checks if the group exists in marathon
// name: the identifier for the group // name: the identifier for the group
func (r *marathonClient) HasGroup(name string) (bool, error) { func (r *marathonClient) HasGroup(name string) (bool, error) {
uri := fmt.Sprintf("%s/%s", marathonAPIGroups, trimRootPath(name)) path := fmt.Sprintf("%s/%s", marathonAPIGroups, trimRootPath(name))
err := r.apiCall("GET", uri, "", nil) err := r.apiCall("GET", path, "", nil)
if err != nil { if err != nil {
if apiErr, ok := err.(*APIError); ok && apiErr.ErrCode == ErrCodeNotFound { if apiErr, ok := err.(*APIError); ok && apiErr.ErrCode == ErrCodeNotFound {
return false, nil return false, nil
@ -208,11 +208,9 @@ func (r *marathonClient) WaitOnGroup(name string, timeout time.Duration) error {
// force: used to force the delete operation in case of blocked deployment // force: used to force the delete operation in case of blocked deployment
func (r *marathonClient) DeleteGroup(name string, force bool) (*DeploymentID, error) { func (r *marathonClient) DeleteGroup(name string, force bool) (*DeploymentID, error) {
version := new(DeploymentID) version := new(DeploymentID)
uri := fmt.Sprintf("%s/%s", marathonAPIGroups, trimRootPath(name)) path := fmt.Sprintf("%s/%s", marathonAPIGroups, trimRootPath(name))
if force { path = buildPathWithForceParam(path, force)
uri = uri + "?force=true" if err := r.apiDelete(path, nil, version); err != nil {
}
if err := r.apiDelete(uri, nil, version); err != nil {
return nil, err return nil, err
} }
@ -225,11 +223,9 @@ func (r *marathonClient) DeleteGroup(name string, force bool) (*DeploymentID, er
// force: used to force the update operation in case of blocked deployment // force: used to force the update operation in case of blocked deployment
func (r *marathonClient) UpdateGroup(name string, group *Group, force bool) (*DeploymentID, error) { func (r *marathonClient) UpdateGroup(name string, group *Group, force bool) (*DeploymentID, error) {
deploymentID := new(DeploymentID) deploymentID := new(DeploymentID)
uri := fmt.Sprintf("%s/%s", marathonAPIGroups, trimRootPath(name)) path := fmt.Sprintf("%s/%s", marathonAPIGroups, trimRootPath(name))
if force { path = buildPathWithForceParam(path, force)
uri = uri + "?force=true" if err := r.apiPut(path, group, deploymentID); err != nil {
}
if err := r.apiPut(uri, group, deploymentID); err != nil {
return nil, err return nil, err
} }

View file

@ -51,8 +51,8 @@ func (r *marathonClient) Queue() (*Queue, error) {
// DeleteQueueDelay resets task launch delay of the specific application // DeleteQueueDelay resets task launch delay of the specific application
// appID: the ID of the application // appID: the ID of the application
func (r *marathonClient) DeleteQueueDelay(appID string) error { func (r *marathonClient) DeleteQueueDelay(appID string) error {
uri := fmt.Sprintf("%s/%s/delay", marathonAPIQueue, trimRootPath(appID)) path := fmt.Sprintf("%s/%s/delay", marathonAPIQueue, trimRootPath(appID))
err := r.apiDelete(uri, nil, nil) err := r.apiDelete(path, nil, nil)
if err != nil { if err != nil {
return err return err
} }

View file

@ -201,8 +201,8 @@ func (r *marathonClient) registerSSESubscription() error {
// Subscribe adds a URL to Marathon's callback facility // Subscribe adds a URL to Marathon's callback facility
// callback : the URL you wish to subscribe // callback : the URL you wish to subscribe
func (r *marathonClient) Subscribe(callback string) error { func (r *marathonClient) Subscribe(callback string) error {
uri := fmt.Sprintf("%s?callbackUrl=%s", marathonAPISubscription, callback) path := fmt.Sprintf("%s?callbackUrl=%s", marathonAPISubscription, callback)
return r.apiPost(uri, "", nil) return r.apiPost(path, "", nil)
} }

View file

@ -79,13 +79,13 @@ func (r *Task) HasHealthCheckResults() bool {
// AllTasks lists tasks of all applications. // AllTasks lists tasks of all applications.
// opts: AllTasksOpts request payload // opts: AllTasksOpts request payload
func (r *marathonClient) AllTasks(opts *AllTasksOpts) (*Tasks, error) { func (r *marathonClient) AllTasks(opts *AllTasksOpts) (*Tasks, error) {
u, err := addOptions(marathonAPITasks, opts) path, err := addOptions(marathonAPITasks, opts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
tasks := new(Tasks) tasks := new(Tasks)
if err := r.apiGet(u, nil, tasks); err != nil { if err := r.apiGet(path, nil, tasks); err != nil {
return nil, err return nil, err
} }
@ -107,14 +107,14 @@ func (r *marathonClient) Tasks(id string) (*Tasks, error) {
// id: the id of the application // id: the id of the application
// opts: KillApplicationTasksOpts request payload // opts: KillApplicationTasksOpts request payload
func (r *marathonClient) KillApplicationTasks(id string, opts *KillApplicationTasksOpts) (*Tasks, error) { func (r *marathonClient) KillApplicationTasks(id string, opts *KillApplicationTasksOpts) (*Tasks, error) {
u := fmt.Sprintf("%s/%s/tasks", marathonAPIApps, trimRootPath(id)) path := fmt.Sprintf("%s/%s/tasks", marathonAPIApps, trimRootPath(id))
u, err := addOptions(u, opts) path, err := addOptions(path, opts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
tasks := new(Tasks) tasks := new(Tasks)
if err := r.apiDelete(u, nil, tasks); err != nil { if err := r.apiDelete(path, nil, tasks); err != nil {
return nil, err return nil, err
} }
@ -129,8 +129,8 @@ func (r *marathonClient) KillTask(taskID string, opts *KillTaskOpts) (*Task, err
appName = strings.Replace(appName, "_", "/", -1) appName = strings.Replace(appName, "_", "/", -1)
taskID = strings.Replace(taskID, "/", "_", -1) taskID = strings.Replace(taskID, "/", "_", -1)
u := fmt.Sprintf("%s/%s/tasks/%s", marathonAPIApps, appName, taskID) path := fmt.Sprintf("%s/%s/tasks/%s", marathonAPIApps, appName, taskID)
u, err := addOptions(u, opts) path, err := addOptions(path, opts)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -139,7 +139,7 @@ func (r *marathonClient) KillTask(taskID string, opts *KillTaskOpts) (*Task, err
Task Task `json:"task"` Task Task `json:"task"`
}) })
if err := r.apiDelete(u, nil, wrappedTask); err != nil { if err := r.apiDelete(path, nil, wrappedTask); err != nil {
return nil, err return nil, err
} }
@ -150,8 +150,8 @@ func (r *marathonClient) KillTask(taskID string, opts *KillTaskOpts) (*Task, err
// tasks: the array of task ids // tasks: the array of task ids
// opts: KillTaskOpts request payload // opts: KillTaskOpts request payload
func (r *marathonClient) KillTasks(tasks []string, opts *KillTaskOpts) error { func (r *marathonClient) KillTasks(tasks []string, opts *KillTaskOpts) error {
u := fmt.Sprintf("%s/delete", marathonAPITasks) path := fmt.Sprintf("%s/delete", marathonAPITasks)
u, err := addOptions(u, opts) path, err := addOptions(path, opts)
if err != nil { if err != nil {
return nil return nil
} }
@ -161,7 +161,7 @@ func (r *marathonClient) KillTasks(tasks []string, opts *KillTaskOpts) error {
} }
post.IDs = tasks post.IDs = tasks
return r.apiPost(u, &post, nil) return r.apiPost(path, &post, nil)
} }
// TaskEndpoints gets the endpoints i.e. HOST_IP:DYNAMIC_PORT for a specific application service // TaskEndpoints gets the endpoints i.e. HOST_IP:DYNAMIC_PORT for a specific application service

View file

@ -0,0 +1,35 @@
/*
Copyright 2017 Rohith All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package marathon
// UnreachableStrategy is the unreachable strategy applied to an application.
type UnreachableStrategy struct {
InactiveAfterSeconds *float64 `json:"inactiveAfterSeconds,omitempty"`
ExpungeAfterSeconds *float64 `json:"expungeAfterSeconds,omitempty"`
}
// SetInactiveAfterSeconds sets the period after which instance will be marked as inactive.
func (us UnreachableStrategy) SetInactiveAfterSeconds(cap float64) UnreachableStrategy {
us.InactiveAfterSeconds = &cap
return us
}
// SetExpungeAfterSeconds sets the period after which instance will be expunged.
func (us UnreachableStrategy) SetExpungeAfterSeconds(cap float64) UnreachableStrategy {
us.ExpungeAfterSeconds = &cap
return us
}