diff --git a/app.go b/app.go index cd9a7cb..c6b2b58 100644 --- a/app.go +++ b/app.go @@ -97,7 +97,7 @@ func (c *Client) UpdateApp(appID string, app *Application) (*Response, error) { } r, err := c.request(options) if r != nil { - if r.Code == 204 { + if (r.Code == 204) || (r.Code == 200) { return r, nil } } @@ -113,7 +113,21 @@ func (c *Client) DeleteApp(appID string) (*Response, error) { } r, err := c.request(options) if r != nil { - if r.Code == 204 { + if r.Code == 200 { + return r, nil + } + } + return nil, err +} + +func (c *Client) DeleteDeployment(deploymentID string) (*Response, error) { + options := &RequestOptions{ + Path: fmt.Sprintf("deployments/%s", deploymentID), + Method: "DELETE", + } + r, err := c.request(options) + if r != nil { + if (r.Code == 200) || (r.Code == 202) { return r, nil } } diff --git a/client.go b/client.go index d24ff23..39d4c51 100644 --- a/client.go +++ b/client.go @@ -15,9 +15,19 @@ import ( // Client is containing the configured http.Client // and the host url +type HttpBasicAuth struct { + User string + Pass string +} + type Client struct { - Host *url.URL + Url string HTTPClient *http.Client + Auth *HttpBasicAuth +} + +type UpdateResp struct { + DeploymentID string `json:"deploymentId"` } // Actual version of the marathon api @@ -26,7 +36,7 @@ const ( ) // NewClient return a pointer to the new client -func NewClient(host string, tlsConfig *tls.Config) (*Client, error) { +func NewClient(host string, auth *HttpBasicAuth, tlsConfig *tls.Config) (*Client, error) { // ValIDate url h, err := url.Parse(host) if err != nil { @@ -34,8 +44,9 @@ func NewClient(host string, tlsConfig *tls.Config) (*Client, error) { } return &Client{ - Host: h, + Url: h.String(), HTTPClient: newHTTPClient(h, tlsConfig), + Auth: auth, }, nil } @@ -52,7 +63,7 @@ func (c *Client) do(method, path string, data interface{}) ([]byte, int, error) params = bytes.NewBuffer(buf) } - req, err := http.NewRequest(method, c.Host.String()+path, params) + req, err := http.NewRequest(method, c.Url+path, params) if err != nil { return nil, -1, err } @@ -61,6 +72,10 @@ func (c *Client) do(method, path string, data interface{}) ([]byte, int, error) req.Header.Set("User-Agent", "gomarathon") req.Header.Set("Content-Type", "application/json") + if c.Auth != nil { + req.SetBasicAuth(c.Auth.User, c.Auth.Pass) + } + resp, err = c.HTTPClient.Do(req) if err != nil { return nil, -1, err @@ -98,11 +113,11 @@ func (c *Client) request(options *RequestOptions) (*Response, error) { v := url.Values{} if options.Params.Cmd != "" { - v.Set("cmd", url.QueryEscape(options.Params.Cmd)) + v.Set("cmd", options.Params.Cmd) } if options.Params.Host != "" { - v.Set("host", url.QueryEscape(options.Params.Host)) + v.Set("host", options.Params.Host) } if options.Params.Scale { @@ -110,7 +125,7 @@ func (c *Client) request(options *RequestOptions) (*Response, error) { } if options.Params.CallbackURL != "" { - v.Set("CallbackURL", url.QueryEscape(options.Params.CallbackURL)) + v.Set("CallbackURL", options.Params.CallbackURL) } path = fmt.Sprintf("%s?%s", path, v.Encode()) @@ -124,6 +139,26 @@ func (c *Client) request(options *RequestOptions) (*Response, error) { Code: code, } + //updated + if resp.Code == 200 { + updateResp := UpdateResp{} + err := json.Unmarshal(data, &updateResp) + if err == nil { + resp.DeploymentId = updateResp.DeploymentID + } else { + fmt.Println("Error unmashaling data response") + } + //created + } else if resp.Code == 201 { + app := Application{} + err := json.Unmarshal(data, &app) + if err == nil { + resp.DeploymentId = app.Deployments[0].ID + } else { + fmt.Println("Error unmashaling data response") + } + } + err = json.Unmarshal(data, resp) if err != nil { return resp, err diff --git a/subscription.go b/subscription.go index d2bf424..f5b15fd 100644 --- a/subscription.go +++ b/subscription.go @@ -2,7 +2,6 @@ package gomarathon import ( "fmt" - "net/url" ) // RegisterCallbackURL register a new callback url @@ -11,7 +10,7 @@ func (c *Client) RegisterCallbackURL(uri string) (*Response, error) { Path: "eventSubscriptions", Method: "POST", Params: &Parameters{ - CallbackURL: url.QueryEscape(uri), + CallbackURL: uri, }, } r, err := c.request(options) @@ -44,7 +43,7 @@ func (c *Client) DeleteCallbackURL(uri string) (*Response, error) { Path: "eventSubscriptions", Method: "DELETE", Params: &Parameters{ - CallbackURL: url.QueryEscape(uri), + CallbackURL: uri, }, } r, err := c.request(options) diff --git a/types.go b/types.go index c66564b..bade8b1 100644 --- a/types.go +++ b/types.go @@ -18,11 +18,12 @@ type Parameters struct { // Response representation of a full marathon response type Response struct { - Code int - Apps []*Application `json:"apps,omitempty"` - App *Application `json:"app,omitempty"` - Versions []string `json:",omitempty"` - Tasks []*Task `json:"tasks,omitempty"` + Code int + Apps []*Application `json:"apps,omitempty"` + App *Application `json:"app,omitempty"` + Versions []string `json:",omitempty"` + Tasks []*Task `json:"tasks,omitempty"` + DeploymentId string `json:"deployment_id,omitempty"` } // Application marathon application see : @@ -48,6 +49,7 @@ type Application struct { UpgradeStrategy *UpgradeStrategy `json:"upgradeStrategy,omitempty"` Uris []string `json:"uris,omitempty"` Version string `json:"version,omitempty"` + Labels map[string]string `json:"labels,omitempty"` } // Container is docker parameters @@ -87,24 +89,35 @@ type UpgradeStrategy struct { // HealthCheck is described here: // https://github.com/mesosphere/marathon/blob/master/REST.md#healthchecks type HealthCheck struct { - Protocol string `json:"protocol,omitempty"` - Path string `json:"path,omitempty"` - GracePeriodSeconds int `json:"gracePeriodSeconds,omitempty"` - IntervalSeconds int `json:"intervalSeconds,omitempty"` - PortIndex int `json:"portIndex,omitempty"` - TimeoutSeconds int `json:"timeoutSeconds,omitempty"` + Protocol string `json:"protocol,omitempty"` + Path string `json:"path,omitempty"` + GracePeriodSeconds int `json:"gracePeriodSeconds,omitempty"` + IntervalSeconds int `json:"intervalSeconds,omitempty"` + PortIndex int `json:"portIndex,omitempty"` + TimeoutSeconds int `json:"timeoutSeconds,omitempty"` + MaxConsecutiveFailures int `json:"maxConsecutiveFailures"` +} + +type HealthCheckResult struct { + Alive bool `json:"alive,omitempty"` + ConsecutiveFailures int `json:"consecutiveFailures,omitempty"` + FirstSuccess string `json:"firstSuccess,omitempty"` + LastFailure string `json:"lastFailure,omitempty"` + LastSuccess string `json:"lastSuccess,omitempty"` + TaskID string `json:"taskId,omitempty"` } // Task is described here: // https://github.com/mesosphere/marathon/blob/master/REST.md#tasks type Task struct { - AppID string `json:"appId"` - Host string `json:"host"` - ID string `json:"id"` - Ports []int `json:"ports"` - StagedAt string `json:"stagedAt"` - StartedAt string `json:"startedAt"` - Version string `json:"version"` + AppID string `json:"appId"` + Host string `json:"host"` + ID string `json:"id"` + Ports []int `json:"ports"` + StagedAt string `json:"stagedAt"` + StartedAt string `json:"startedAt"` + Version string `json:"version"` + HealthCheckResults []*HealthCheckResult `json:"healthCheckResults"` } // Deployment is described here: