2016-03-18 15:33:07 +01:00
|
|
|
package status
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/url"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/CenturyLinkCloud/clc-sdk/api"
|
|
|
|
)
|
|
|
|
|
|
|
|
func New(client api.HTTP) *Service {
|
|
|
|
return &Service{
|
|
|
|
client: client,
|
|
|
|
config: client.Config(),
|
|
|
|
PollInterval: 30 * time.Second,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type Service struct {
|
|
|
|
client api.HTTP
|
|
|
|
config *api.Config
|
|
|
|
|
|
|
|
PollInterval time.Duration
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Service) Get(id string) (*Response, error) {
|
|
|
|
url := fmt.Sprintf("%s/operations/%s/status/%s", s.config.BaseURL, s.config.Alias, id)
|
|
|
|
status := &Response{}
|
|
|
|
err := s.client.Get(url, status)
|
|
|
|
return status, err
|
|
|
|
}
|
|
|
|
|
2016-04-29 18:50:34 +02:00
|
|
|
func (s *Service) GetBlueprint(id string) (*BlueprintOperation, error) {
|
|
|
|
url := fmt.Sprintf("%s/operations/%s/status/%s", s.config.BaseURL, s.config.Alias, id)
|
|
|
|
status := &BlueprintOperation{}
|
|
|
|
err := s.client.Get(url, status)
|
|
|
|
return status, err
|
|
|
|
}
|
|
|
|
|
2016-03-18 15:33:07 +01:00
|
|
|
func (s *Service) Poll(id string, poll chan *Response) error {
|
|
|
|
for {
|
|
|
|
status, err := s.Get(id)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if !status.Running() {
|
|
|
|
poll <- status
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
time.Sleep(s.PollInterval)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type Status struct {
|
|
|
|
ID string `json:"id"`
|
|
|
|
Rel string `json:"rel"`
|
|
|
|
Href string `json:"href"`
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Response represents a running async job
|
|
|
|
result from polling status
|
|
|
|
{"status": "succeeded"}
|
|
|
|
*/
|
|
|
|
type Response struct {
|
|
|
|
Status string `json:"status"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Response) Complete() bool {
|
|
|
|
return s.Status == Complete
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Response) Failed() bool {
|
|
|
|
return s.Status == Failed
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Response) Running() bool {
|
|
|
|
return !s.Complete() && !s.Failed() && s.Status != ""
|
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
|
|
|
Complete = "succeeded"
|
|
|
|
Failed = "failed"
|
|
|
|
)
|
|
|
|
|
|
|
|
/* QueuedResponse represents a returned response for an async platform job
|
|
|
|
eg. create server
|
|
|
|
{"server":"web", "isQueued":true, "links":[
|
|
|
|
{"rel":"status", "href":"...", "id":"wa1-12345"},
|
|
|
|
{"rel":"self", "href":"...", "id":"8134c91a66784c6dada651eba90a5123"}]}
|
|
|
|
*/
|
|
|
|
type QueuedResponse struct {
|
|
|
|
Server string `json:"server,omitempty"`
|
|
|
|
IsQueued bool `json:"isQueued,omitempty"`
|
|
|
|
Links api.Links `json:"links,omitempty"`
|
|
|
|
Error string `json:"errorMessage,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *QueuedResponse) GetStatusID() (bool, string) {
|
|
|
|
return q.Links.GetID("status")
|
|
|
|
}
|
|
|
|
|
|
|
|
/* QueuedOperation may be a one-off and/or experimental version of QueuedResponse
|
|
|
|
eg. add secondary network
|
|
|
|
{"operationId": "2b70710dba4142dcaf3ab2de68e4f40c", "uri": "..."}
|
|
|
|
*/
|
|
|
|
type QueuedOperation struct {
|
|
|
|
OperationID string `json:"operationId,omitempty"`
|
|
|
|
URI string `json:"uri,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *QueuedOperation) GetStatusID() (bool, string) {
|
|
|
|
return q.OperationID != "", q.OperationID
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *QueuedOperation) GetHref() (bool, string) {
|
|
|
|
var path = ""
|
|
|
|
if q.URI != "" {
|
|
|
|
u, err := url.Parse(q.URI)
|
|
|
|
if err == nil {
|
|
|
|
path = u.Path
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return path != "", path
|
|
|
|
}
|
|
|
|
|
|
|
|
func (q *QueuedOperation) Status() *Status {
|
|
|
|
st := &Status{}
|
|
|
|
if ok, id := q.GetStatusID(); ok {
|
|
|
|
st.ID = id
|
|
|
|
}
|
|
|
|
if ok, href := q.GetHref(); ok {
|
|
|
|
st.Href = href
|
|
|
|
}
|
|
|
|
return st
|
|
|
|
}
|
2016-04-29 18:50:34 +02:00
|
|
|
|
|
|
|
/* BlueprintOperation is a status object representing a running blueprint job
|
|
|
|
{
|
|
|
|
"requestType":"blueprintOperation",
|
|
|
|
"status":"succeeded",
|
|
|
|
"summary":{
|
|
|
|
"blueprintId":51229,
|
|
|
|
"locationId":"CA1",
|
|
|
|
"links":[
|
|
|
|
{
|
|
|
|
"rel":"network",
|
|
|
|
"href":"/v2-experimental/networks/ZZBB/CA1/6955e7c39b5648df91bfb32e5d0aa24b",
|
|
|
|
"id":"6955e7c39b5648df91bfb32e5d0aa24b"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"source":{"userName":"ack","requestedAt":"2016-03-24T16:47:04Z"}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
type BlueprintOperation struct {
|
|
|
|
RequestType string `json:"requestType,omitempty"`
|
|
|
|
Status string `json:"status,omitempty"`
|
|
|
|
Summary struct {
|
|
|
|
BlueprintID int `json:"blueprintId,omitempty"`
|
|
|
|
LocationID string `json:"locationId,omitempty"`
|
|
|
|
Links api.Links `json:"links,omitempty"`
|
|
|
|
} `json:"summary,omitempty"`
|
|
|
|
Source struct {
|
|
|
|
UserName string `json:"userName"`
|
|
|
|
RequestedAt time.Time `json:"requestedAt,omitempty"`
|
|
|
|
} `json:"source,omitempty"`
|
|
|
|
}
|