435c0d9fc8
This PR switches the Nomad repository from using govendor to Go modules for managing dependencies. Aspects of the Nomad workflow remain pretty much the same. The usual Makefile targets should continue to work as they always did. The API submodule simply defers to the parent Nomad version on the repository, keeping the semantics of API versioning that currently exists.
209 lines
5.9 KiB
Go
209 lines
5.9 KiB
Go
package linodego
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// Stackscript represents a Linode StackScript
|
|
type Stackscript struct {
|
|
CreatedStr string `json:"created"`
|
|
UpdatedStr string `json:"updated"`
|
|
|
|
ID int `json:"id"`
|
|
Username string `json:"username"`
|
|
Label string `json:"label"`
|
|
Description string `json:"description"`
|
|
Images []string `json:"images"`
|
|
DeploymentsTotal int `json:"deployments_total"`
|
|
DeploymentsActive int `json:"deployments_active"`
|
|
IsPublic bool `json:"is_public"`
|
|
Created *time.Time `json:"-"`
|
|
Updated *time.Time `json:"-"`
|
|
RevNote string `json:"rev_note"`
|
|
Script string `json:"script"`
|
|
UserDefinedFields *[]StackscriptUDF `json:"user_defined_fields"`
|
|
UserGravatarID string `json:"user_gravatar_id"`
|
|
}
|
|
|
|
// StackscriptUDF define a single variable that is accepted by a Stackscript
|
|
type StackscriptUDF struct {
|
|
// A human-readable label for the field that will serve as the input prompt for entering the value during deployment.
|
|
Label string `json:"label"`
|
|
|
|
// The name of the field.
|
|
Name string `json:"name"`
|
|
|
|
// An example value for the field.
|
|
Example string `json:"example"`
|
|
|
|
// A list of acceptable single values for the field.
|
|
OneOf string `json:"oneOf,omitempty"`
|
|
|
|
// A list of acceptable values for the field in any quantity, combination or order.
|
|
ManyOf string `json:"manyOf,omitempty"`
|
|
|
|
// The default value. If not specified, this value will be used.
|
|
Default string `json:"default,omitempty"`
|
|
}
|
|
|
|
// StackscriptCreateOptions fields are those accepted by CreateStackscript
|
|
type StackscriptCreateOptions struct {
|
|
Label string `json:"label"`
|
|
Description string `json:"description"`
|
|
Images []string `json:"images"`
|
|
IsPublic bool `json:"is_public"`
|
|
RevNote string `json:"rev_note"`
|
|
Script string `json:"script"`
|
|
}
|
|
|
|
// StackscriptUpdateOptions fields are those accepted by UpdateStackscript
|
|
type StackscriptUpdateOptions StackscriptCreateOptions
|
|
|
|
// GetCreateOptions converts a Stackscript to StackscriptCreateOptions for use in CreateStackscript
|
|
func (i Stackscript) GetCreateOptions() StackscriptCreateOptions {
|
|
return StackscriptCreateOptions{
|
|
Label: i.Label,
|
|
Description: i.Description,
|
|
Images: i.Images,
|
|
IsPublic: i.IsPublic,
|
|
RevNote: i.RevNote,
|
|
Script: i.Script,
|
|
}
|
|
}
|
|
|
|
// GetUpdateOptions converts a Stackscript to StackscriptUpdateOptions for use in UpdateStackscript
|
|
func (i Stackscript) GetUpdateOptions() StackscriptUpdateOptions {
|
|
return StackscriptUpdateOptions{
|
|
Label: i.Label,
|
|
Description: i.Description,
|
|
Images: i.Images,
|
|
IsPublic: i.IsPublic,
|
|
RevNote: i.RevNote,
|
|
Script: i.Script,
|
|
}
|
|
}
|
|
|
|
// StackscriptsPagedResponse represents a paginated Stackscript API response
|
|
type StackscriptsPagedResponse struct {
|
|
*PageOptions
|
|
Data []Stackscript `json:"data"`
|
|
}
|
|
|
|
// endpoint gets the endpoint URL for Stackscript
|
|
func (StackscriptsPagedResponse) endpoint(c *Client) string {
|
|
endpoint, err := c.StackScripts.Endpoint()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return endpoint
|
|
}
|
|
|
|
// appendData appends Stackscripts when processing paginated Stackscript responses
|
|
func (resp *StackscriptsPagedResponse) appendData(r *StackscriptsPagedResponse) {
|
|
resp.Data = append(resp.Data, r.Data...)
|
|
}
|
|
|
|
// ListStackscripts lists Stackscripts
|
|
func (c *Client) ListStackscripts(ctx context.Context, opts *ListOptions) ([]Stackscript, error) {
|
|
response := StackscriptsPagedResponse{}
|
|
err := c.listHelper(ctx, &response, opts)
|
|
for i := range response.Data {
|
|
response.Data[i].fixDates()
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return response.Data, nil
|
|
}
|
|
|
|
// fixDates converts JSON timestamps to Go time.Time values
|
|
func (i *Stackscript) fixDates() *Stackscript {
|
|
i.Created, _ = parseDates(i.CreatedStr)
|
|
i.Updated, _ = parseDates(i.UpdatedStr)
|
|
return i
|
|
}
|
|
|
|
// GetStackscript gets the Stackscript with the provided ID
|
|
func (c *Client) GetStackscript(ctx context.Context, id int) (*Stackscript, error) {
|
|
e, err := c.StackScripts.Endpoint()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
e = fmt.Sprintf("%s/%d", e, id)
|
|
r, err := coupleAPIErrors(c.R(ctx).
|
|
SetResult(&Stackscript{}).
|
|
Get(e))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return r.Result().(*Stackscript).fixDates(), nil
|
|
}
|
|
|
|
// CreateStackscript creates a StackScript
|
|
func (c *Client) CreateStackscript(ctx context.Context, createOpts StackscriptCreateOptions) (*Stackscript, error) {
|
|
var body string
|
|
e, err := c.StackScripts.Endpoint()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req := c.R(ctx).SetResult(&Stackscript{})
|
|
|
|
if bodyData, err := json.Marshal(createOpts); err == nil {
|
|
body = string(bodyData)
|
|
} else {
|
|
return nil, NewError(err)
|
|
}
|
|
|
|
r, err := coupleAPIErrors(req.
|
|
SetBody(body).
|
|
Post(e))
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return r.Result().(*Stackscript).fixDates(), nil
|
|
}
|
|
|
|
// UpdateStackscript updates the StackScript with the specified id
|
|
func (c *Client) UpdateStackscript(ctx context.Context, id int, updateOpts StackscriptUpdateOptions) (*Stackscript, error) {
|
|
var body string
|
|
e, err := c.StackScripts.Endpoint()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
e = fmt.Sprintf("%s/%d", e, id)
|
|
|
|
req := c.R(ctx).SetResult(&Stackscript{})
|
|
|
|
if bodyData, err := json.Marshal(updateOpts); err == nil {
|
|
body = string(bodyData)
|
|
} else {
|
|
return nil, NewError(err)
|
|
}
|
|
|
|
r, err := coupleAPIErrors(req.
|
|
SetBody(body).
|
|
Put(e))
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return r.Result().(*Stackscript).fixDates(), nil
|
|
}
|
|
|
|
// DeleteStackscript deletes the StackScript with the specified id
|
|
func (c *Client) DeleteStackscript(ctx context.Context, id int) error {
|
|
e, err := c.StackScripts.Endpoint()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
e = fmt.Sprintf("%s/%d", e, id)
|
|
|
|
_, err = coupleAPIErrors(c.R(ctx).Delete(e))
|
|
return err
|
|
}
|