terraform/vendor/github.com/joyent/triton-go/machines.go

473 lines
13 KiB
Go
Raw Normal View History

provider/triton: Move to joyent/triton-go (#13225) * provider/triton: Move to joyent/triton-go This commit moves the Triton provider to the new joyent/triton-go library from gosdc. This has a number of advantages - not least that requests can be signed using an SSH agent without having to keep unencrypted key material in memory. Schema has been maintained for all resources, and several tests have been added and acceptance tests repaired - in some cases by fixing bugs in the underlying resources. After applying this patch, all acceptance tests pass: ``` go generate $(go list ./... | grep -v /terraform/vendor/) 2017/03/30 13:48:33 Generated command/internal_plugin_list.go TF_ACC=1 go test ./builtin/providers/triton -v -timeout 120m === RUN TestProvider --- PASS: TestProvider (0.00s) === RUN TestProvider_impl --- PASS: TestProvider_impl (0.00s) === RUN TestAccTritonFabric_basic --- PASS: TestAccTritonFabric_basic (15.11s) === RUN TestAccTritonFirewallRule_basic --- PASS: TestAccTritonFirewallRule_basic (1.48s) === RUN TestAccTritonFirewallRule_update --- PASS: TestAccTritonFirewallRule_update (1.55s) === RUN TestAccTritonFirewallRule_enable --- PASS: TestAccTritonFirewallRule_enable (1.52s) === RUN TestAccTritonKey_basic --- PASS: TestAccTritonKey_basic (11.76s) === RUN TestAccTritonKey_noKeyName --- PASS: TestAccTritonKey_noKeyName (11.20s) === RUN TestAccTritonMachine_basic --- PASS: TestAccTritonMachine_basic (82.19s) === RUN TestAccTritonMachine_dns --- PASS: TestAccTritonMachine_dns (173.36s) === RUN TestAccTritonMachine_nic --- PASS: TestAccTritonMachine_nic (167.82s) === RUN TestAccTritonMachine_addNIC --- PASS: TestAccTritonMachine_addNIC (192.11s) === RUN TestAccTritonMachine_firewall --- PASS: TestAccTritonMachine_firewall (188.53s) === RUN TestAccTritonMachine_metadata --- PASS: TestAccTritonMachine_metadata (614.57s) === RUN TestAccTritonVLAN_basic --- PASS: TestAccTritonVLAN_basic (0.93s) === RUN TestAccTritonVLAN_update --- PASS: TestAccTritonVLAN_update (1.50s) PASS ok github.com/hashicorp/terraform/builtin/providers/triton 1463.621s ``` * provider/triton: Update docs for provider config * deps: Vendor github.com/joyent/triton-go/... * deps: Remove github.com/joyent/gosdc
2017-03-31 00:25:27 +02:00
package triton
import (
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/hashicorp/errwrap"
"net/url"
)
type MachinesClient struct {
*Client
}
// Machines returns a client used for accessing functions pertaining to
// machine functionality in the Triton API.
func (c *Client) Machines() *MachinesClient {
return &MachinesClient{c}
}
type Machine struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Brand string `json:"brand"`
State string `json:"state"`
Image string `json:"image"`
Memory int `json:"memory"`
Disk int `json:"disk"`
Metadata map[string]string `json:"metadata"`
Tags map[string]string `json:"tags"`
Created time.Time `json:"created"`
Updated time.Time `json:"updated"`
Docker bool `json:"docker"`
IPs []string `json:"ips"`
Networks []string `json:"networks"`
PrimaryIP string `json:"primaryIp"`
FirewallEnabled bool `json:"firewall_enabled"`
ComputeNode string `json:"compute_node"`
Package string `json:"package"`
DomainNames []string `json:"dns_names"`
}
type NIC struct {
IP string `json:"ip"`
MAC string `json:"mac"`
Primary bool `json:"primary"`
Netmask string `json:"netmask"`
Gateway string `json:"gateway"`
State string `json:"state"`
Network string `json:"network"`
}
type GetMachineInput struct {
ID string
}
func (client *MachinesClient) GetMachine(input *GetMachineInput) (*Machine, error) {
path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID)
response, err := client.executeRequestRaw(http.MethodGet, path, nil)
if response != nil {
defer response.Body.Close()
}
if response.StatusCode == http.StatusNotFound {
return nil, &TritonError{
Code: "ResourceNotFound",
}
}
if err != nil {
return nil, errwrap.Wrapf("Error executing GetMachine request: {{err}}",
client.decodeError(response.StatusCode, response.Body))
}
var result *Machine
decoder := json.NewDecoder(response.Body)
if err = decoder.Decode(&result); err != nil {
return nil, errwrap.Wrapf("Error decoding GetMachine response: {{err}}", err)
}
return result, nil
}
type CreateMachineInput struct {
Name string
Package string
Image string
Networks []string
LocalityStrict bool
LocalityNear []string
LocalityFar []string
Metadata map[string]string
Tags map[string]string
FirewallEnabled bool
}
func transformCreateMachineInput(input *CreateMachineInput) map[string]interface{} {
result := make(map[string]interface{}, 8+len(input.Metadata)+len(input.Tags))
result["firewall_enabled"] = input.FirewallEnabled
if input.Name != "" {
result["name"] = input.Name
}
if input.Package != "" {
result["package"] = input.Package
}
if input.Image != "" {
result["image"] = input.Image
}
if len(input.Networks) > 0 {
result["networks"] = input.Networks
}
locality := struct {
Strict bool `json:"strict"`
Near []string `json:"near,omitempty"`
Far []string `json:"far,omitempty"`
}{
Strict: input.LocalityStrict,
Near: input.LocalityNear,
Far: input.LocalityFar,
}
result["locality"] = locality
for key, value := range input.Tags {
result[fmt.Sprintf("tag.%s", key)] = value
}
for key, value := range input.Metadata {
result[fmt.Sprintf("metadata.%s", key)] = value
}
return result
}
func (client *MachinesClient) CreateMachine(input *CreateMachineInput) (*Machine, error) {
respReader, err := client.executeRequest(http.MethodPost, "/my/machines", transformCreateMachineInput(input))
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return nil, errwrap.Wrapf("Error executing CreateMachine request: {{err}}", err)
}
var result *Machine
decoder := json.NewDecoder(respReader)
if err = decoder.Decode(&result); err != nil {
return nil, errwrap.Wrapf("Error decoding CreateMachine response: {{err}}", err)
}
return result, nil
}
type DeleteMachineInput struct {
ID string
}
func (client *MachinesClient) DeleteMachine(input *DeleteMachineInput) error {
path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID)
response, err := client.executeRequestRaw(http.MethodDelete, path, nil)
if response.Body != nil {
defer response.Body.Close()
}
if response.StatusCode == http.StatusNotFound {
return nil
}
if err != nil {
return errwrap.Wrapf("Error executing DeleteMachine request: {{err}}",
client.decodeError(response.StatusCode, response.Body))
}
return nil
}
type DeleteMachineTagsInput struct {
ID string
}
func (client *MachinesClient) DeleteMachineTags(input *DeleteMachineTagsInput) error {
path := fmt.Sprintf("/%s/machines/%s/tags", client.accountName, input.ID)
response, err := client.executeRequestRaw(http.MethodDelete, path, nil)
if response.Body != nil {
defer response.Body.Close()
}
if response.StatusCode == http.StatusNotFound {
return nil
}
if err != nil {
return errwrap.Wrapf("Error executing DeleteMachineTags request: {{err}}",
client.decodeError(response.StatusCode, response.Body))
}
return nil
}
type DeleteMachineTagInput struct {
ID string
Key string
}
func (client *MachinesClient) DeleteMachineTag(input *DeleteMachineTagInput) error {
path := fmt.Sprintf("/%s/machines/%s/tags/%s", client.accountName, input.ID, input.Key)
response, err := client.executeRequestRaw(http.MethodDelete, path, nil)
if response.Body != nil {
defer response.Body.Close()
}
if response.StatusCode == http.StatusNotFound {
return nil
}
if err != nil {
return errwrap.Wrapf("Error executing DeleteMachineTag request: {{err}}",
client.decodeError(response.StatusCode, response.Body))
}
return nil
}
type RenameMachineInput struct {
ID string
Name string
}
func (client *MachinesClient) RenameMachine(input *RenameMachineInput) error {
path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID)
params := &url.Values{}
params.Set("action", "rename")
params.Set("name", input.Name)
respReader, err := client.executeRequestURIParams(http.MethodPost, path, nil, params)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return errwrap.Wrapf("Error executing RenameMachine request: {{err}}", err)
}
return nil
}
type ReplaceMachineTagsInput struct {
ID string
Tags map[string]string
}
func (client *MachinesClient) ReplaceMachineTags(input *ReplaceMachineTagsInput) error {
path := fmt.Sprintf("/%s/machines/%s/tags", client.accountName, input.ID)
respReader, err := client.executeRequest(http.MethodPut, path, input.Tags)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return errwrap.Wrapf("Error executing ReplaceMachineTags request: {{err}}", err)
}
return nil
}
type AddMachineTagsInput struct {
ID string
Tags map[string]string
}
func (client *MachinesClient) AddMachineTags(input *AddMachineTagsInput) error {
path := fmt.Sprintf("/%s/machines/%s/tags", client.accountName, input.ID)
respReader, err := client.executeRequest(http.MethodPost, path, input.Tags)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return errwrap.Wrapf("Error executing AddMachineTags request: {{err}}", err)
}
return nil
}
type GetMachineTagInput struct {
ID string
Key string
}
func (client *MachinesClient) GetMachineTag(input *GetMachineTagInput) (string, error) {
path := fmt.Sprintf("/%s/machines/%s/tags/%s", client.accountName, input.ID, input.Key)
respReader, err := client.executeRequest(http.MethodGet, path, nil)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return "", errwrap.Wrapf("Error executing GetMachineTag request: {{err}}", err)
}
var result string
decoder := json.NewDecoder(respReader)
if err = decoder.Decode(&result); err != nil {
return "", errwrap.Wrapf("Error decoding GetMachineTag response: {{err}}", err)
}
return result, nil
}
type ListMachineTagsInput struct {
ID string
}
func (client *MachinesClient) ListMachineTags(input *ListMachineTagsInput) (map[string]string, error) {
path := fmt.Sprintf("/%s/machines/%s/tags", client.accountName, input.ID)
respReader, err := client.executeRequest(http.MethodGet, path, nil)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return nil, errwrap.Wrapf("Error executing ListMachineTags request: {{err}}", err)
}
var result map[string]string
decoder := json.NewDecoder(respReader)
if err = decoder.Decode(&result); err != nil {
return nil, errwrap.Wrapf("Error decoding ListMachineTags response: {{err}}", err)
}
return result, nil
}
type UpdateMachineMetadataInput struct {
ID string
Metadata map[string]string
}
func (client *MachinesClient) UpdateMachineMetadata(input *UpdateMachineMetadataInput) (map[string]string, error) {
path := fmt.Sprintf("/%s/machines/%s/tags", client.accountName, input.ID)
respReader, err := client.executeRequest(http.MethodPost, path, input.Metadata)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return nil, errwrap.Wrapf("Error executing UpdateMachineMetadata request: {{err}}", err)
}
var result map[string]string
decoder := json.NewDecoder(respReader)
if err = decoder.Decode(&result); err != nil {
return nil, errwrap.Wrapf("Error decoding UpdateMachineMetadata response: {{err}}", err)
}
return result, nil
}
type ResizeMachineInput struct {
ID string
Package string
}
func (client *MachinesClient) ResizeMachine(input *ResizeMachineInput) error {
path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID)
params := &url.Values{}
params.Set("action", "resize")
params.Set("package", input.Package)
respReader, err := client.executeRequestURIParams(http.MethodPost, path, nil, params)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return errwrap.Wrapf("Error executing ResizeMachine request: {{err}}", err)
}
return nil
}
type EnableMachineFirewallInput struct {
ID string
}
func (client *MachinesClient) EnableMachineFirewall(input *EnableMachineFirewallInput) error {
path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID)
params := &url.Values{}
params.Set("action", "enable_firewall")
respReader, err := client.executeRequestURIParams(http.MethodPost, path, nil, params)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return errwrap.Wrapf("Error executing EnableMachineFirewall request: {{err}}", err)
}
return nil
}
type DisableMachineFirewallInput struct {
ID string
}
func (client *MachinesClient) DisableMachineFirewall(input *DisableMachineFirewallInput) error {
path := fmt.Sprintf("/%s/machines/%s", client.accountName, input.ID)
params := &url.Values{}
params.Set("action", "disable_firewall")
respReader, err := client.executeRequestURIParams(http.MethodPost, path, nil, params)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return errwrap.Wrapf("Error executing DisableMachineFirewall request: {{err}}", err)
}
return nil
}
type ListNICsInput struct {
MachineID string
}
func (client *MachinesClient) ListNICs(input *ListNICsInput) ([]*NIC, error) {
respReader, err := client.executeRequest(http.MethodGet, fmt.Sprintf("/my/machines/%s/nics", input.MachineID), nil)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return nil, errwrap.Wrapf("Error executing ListNICs request: {{err}}", err)
}
var result []*NIC
decoder := json.NewDecoder(respReader)
if err = decoder.Decode(&result); err != nil {
return nil, errwrap.Wrapf("Error decoding ListNICs response: {{err}}", err)
}
return result, nil
}
type AddNICInput struct {
MachineID string `json:"-"`
Network string `json:"network"`
}
func (client *MachinesClient) AddNIC(input *AddNICInput) (*NIC, error) {
path := fmt.Sprintf("/%s/machines/%s/nics", client.accountName, input.MachineID)
respReader, err := client.executeRequest(http.MethodPost, path, input)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return nil, errwrap.Wrapf("Error executing AddNIC request: {{err}}", err)
}
var result *NIC
decoder := json.NewDecoder(respReader)
if err = decoder.Decode(&result); err != nil {
return nil, errwrap.Wrapf("Error decoding AddNIC response: {{err}}", err)
}
return result, nil
}
type RemoveNICInput struct {
MachineID string
MAC string
}
func (client *MachinesClient) RemoveNIC(input *RemoveNICInput) error {
path := fmt.Sprintf("/%s/machines/%s/nics/%s", client.accountName, input.MachineID, input.MAC)
respReader, err := client.executeRequest(http.MethodDelete, path, nil)
if respReader != nil {
defer respReader.Close()
}
if err != nil {
return errwrap.Wrapf("Error executing RemoveNIC request: {{err}}", err)
}
return nil
}