2020-06-18 15:04:41 +00:00
|
|
|
package godo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
const vpcsBasePath = "/v2/vpcs"
|
|
|
|
|
|
|
|
// VPCsService is an interface for managing Virtual Private Cloud configurations with the
|
|
|
|
// DigitalOcean API.
|
|
|
|
// See: https://developers.digitalocean.com/documentation/v2#vpcs
|
|
|
|
type VPCsService interface {
|
|
|
|
Create(context.Context, *VPCCreateRequest) (*VPC, *Response, error)
|
|
|
|
Get(context.Context, string) (*VPC, *Response, error)
|
|
|
|
List(context.Context, *ListOptions) ([]*VPC, *Response, error)
|
|
|
|
Update(context.Context, string, *VPCUpdateRequest) (*VPC, *Response, error)
|
|
|
|
Set(context.Context, string, ...VPCSetField) (*VPC, *Response, error)
|
|
|
|
Delete(context.Context, string) (*Response, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ VPCsService = &VPCsServiceOp{}
|
|
|
|
|
|
|
|
// VPCsServiceOp interfaces with VPC endpoints in the DigitalOcean API.
|
|
|
|
type VPCsServiceOp struct {
|
|
|
|
client *Client
|
|
|
|
}
|
|
|
|
|
|
|
|
// VPCCreateRequest represents a request to create a Virtual Private Cloud.
|
|
|
|
type VPCCreateRequest struct {
|
|
|
|
Name string `json:"name,omitempty"`
|
|
|
|
RegionSlug string `json:"region,omitempty"`
|
|
|
|
Description string `json:"description,omitempty"`
|
|
|
|
IPRange string `json:"ip_range,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// VPCUpdateRequest represents a request to update a Virtual Private Cloud.
|
|
|
|
type VPCUpdateRequest struct {
|
|
|
|
Name string `json:"name,omitempty"`
|
|
|
|
Description string `json:"description,omitempty"`
|
2020-11-19 14:02:19 +00:00
|
|
|
Default *bool `json:"default,omitempty"`
|
2020-06-18 15:04:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// VPCSetField allows one to set individual fields within a VPC configuration.
|
|
|
|
type VPCSetField interface {
|
|
|
|
vpcSetField(map[string]interface{})
|
|
|
|
}
|
|
|
|
|
|
|
|
// VPCSetName is used when one want to set the `name` field of a VPC.
|
|
|
|
// Ex.: VPCs.Set(..., VPCSetName("new-name"))
|
|
|
|
type VPCSetName string
|
|
|
|
|
|
|
|
// VPCSetDescription is used when one want to set the `description` field of a VPC.
|
|
|
|
// Ex.: VPCs.Set(..., VPCSetDescription("vpc description"))
|
|
|
|
type VPCSetDescription string
|
|
|
|
|
2020-11-19 14:02:19 +00:00
|
|
|
// VPCSetDefault is used when one wants to enable the `default` field of a VPC, to
|
|
|
|
// set a VPC as the default one in the region
|
|
|
|
// Ex.: VPCs.Set(..., VPCSetDefault())
|
|
|
|
func VPCSetDefault() VPCSetField {
|
|
|
|
return &vpcSetDefault{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// vpcSetDefault satisfies the VPCSetField interface
|
|
|
|
type vpcSetDefault struct{}
|
|
|
|
|
2020-06-18 15:04:41 +00:00
|
|
|
// VPC represents a DigitalOcean Virtual Private Cloud configuration.
|
|
|
|
type VPC struct {
|
|
|
|
ID string `json:"id,omitempty"`
|
|
|
|
URN string `json:"urn"`
|
|
|
|
Name string `json:"name,omitempty"`
|
|
|
|
Description string `json:"description,omitempty"`
|
|
|
|
IPRange string `json:"ip_range,omitempty"`
|
|
|
|
RegionSlug string `json:"region,omitempty"`
|
|
|
|
CreatedAt time.Time `json:"created_at,omitempty"`
|
|
|
|
Default bool `json:"default,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type vpcRoot struct {
|
|
|
|
VPC *VPC `json:"vpc"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type vpcsRoot struct {
|
|
|
|
VPCs []*VPC `json:"vpcs"`
|
|
|
|
Links *Links `json:"links"`
|
|
|
|
Meta *Meta `json:"meta"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get returns the details of a Virtual Private Cloud.
|
|
|
|
func (v *VPCsServiceOp) Get(ctx context.Context, id string) (*VPC, *Response, error) {
|
|
|
|
path := vpcsBasePath + "/" + id
|
|
|
|
req, err := v.client.NewRequest(ctx, http.MethodGet, path, nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
root := new(vpcRoot)
|
|
|
|
resp, err := v.client.Do(ctx, req, root)
|
|
|
|
if err != nil {
|
|
|
|
return nil, resp, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return root.VPC, resp, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create creates a new Virtual Private Cloud.
|
|
|
|
func (v *VPCsServiceOp) Create(ctx context.Context, create *VPCCreateRequest) (*VPC, *Response, error) {
|
|
|
|
path := vpcsBasePath
|
|
|
|
req, err := v.client.NewRequest(ctx, http.MethodPost, path, create)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
root := new(vpcRoot)
|
|
|
|
resp, err := v.client.Do(ctx, req, root)
|
|
|
|
if err != nil {
|
|
|
|
return nil, resp, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return root.VPC, resp, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// List returns a list of the caller's VPCs, with optional pagination.
|
|
|
|
func (v *VPCsServiceOp) List(ctx context.Context, opt *ListOptions) ([]*VPC, *Response, error) {
|
|
|
|
path, err := addOptions(vpcsBasePath, opt)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
req, err := v.client.NewRequest(ctx, http.MethodGet, path, nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
root := new(vpcsRoot)
|
|
|
|
resp, err := v.client.Do(ctx, req, root)
|
|
|
|
if err != nil {
|
|
|
|
return nil, resp, err
|
|
|
|
}
|
|
|
|
if l := root.Links; l != nil {
|
|
|
|
resp.Links = l
|
|
|
|
}
|
|
|
|
if m := root.Meta; m != nil {
|
|
|
|
resp.Meta = m
|
|
|
|
}
|
|
|
|
|
|
|
|
return root.VPCs, resp, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update updates a Virtual Private Cloud's properties.
|
|
|
|
func (v *VPCsServiceOp) Update(ctx context.Context, id string, update *VPCUpdateRequest) (*VPC, *Response, error) {
|
|
|
|
path := vpcsBasePath + "/" + id
|
|
|
|
req, err := v.client.NewRequest(ctx, http.MethodPut, path, update)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
root := new(vpcRoot)
|
|
|
|
resp, err := v.client.Do(ctx, req, root)
|
|
|
|
if err != nil {
|
|
|
|
return nil, resp, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return root.VPC, resp, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n VPCSetName) vpcSetField(in map[string]interface{}) {
|
|
|
|
in["name"] = n
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n VPCSetDescription) vpcSetField(in map[string]interface{}) {
|
|
|
|
in["description"] = n
|
|
|
|
}
|
|
|
|
|
2020-11-19 14:02:19 +00:00
|
|
|
func (*vpcSetDefault) vpcSetField(in map[string]interface{}) {
|
|
|
|
in["default"] = true
|
|
|
|
}
|
|
|
|
|
2020-06-18 15:04:41 +00:00
|
|
|
// Set updates specific properties of a Virtual Private Cloud.
|
|
|
|
func (v *VPCsServiceOp) Set(ctx context.Context, id string, fields ...VPCSetField) (*VPC, *Response, error) {
|
|
|
|
path := vpcsBasePath + "/" + id
|
|
|
|
update := make(map[string]interface{}, len(fields))
|
|
|
|
for _, field := range fields {
|
|
|
|
field.vpcSetField(update)
|
|
|
|
}
|
|
|
|
|
|
|
|
req, err := v.client.NewRequest(ctx, http.MethodPatch, path, update)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
root := new(vpcRoot)
|
|
|
|
resp, err := v.client.Do(ctx, req, root)
|
|
|
|
if err != nil {
|
|
|
|
return nil, resp, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return root.VPC, resp, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete deletes a Virtual Private Cloud. There is no way to recover a VPC once it has been
|
|
|
|
// destroyed.
|
|
|
|
func (v *VPCsServiceOp) Delete(ctx context.Context, id string) (*Response, error) {
|
|
|
|
path := vpcsBasePath + "/" + id
|
|
|
|
req, err := v.client.NewRequest(ctx, http.MethodDelete, path, nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := v.client.Do(ctx, req, nil)
|
|
|
|
if err != nil {
|
|
|
|
return resp, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return resp, nil
|
|
|
|
}
|