roll out vpc functionality
This commit is contained in:
parent
87f69d1b82
commit
6760694045
|
@ -60,6 +60,7 @@ type Droplet struct {
|
|||
Kernel *Kernel `json:"kernel,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
VolumeIDs []string `json:"volume_ids"`
|
||||
VPCUUID string `json:"vpc_uuid,omitempty"`
|
||||
}
|
||||
|
||||
// PublicIPv4 returns the public IPv4 address for the Droplet.
|
||||
|
@ -222,6 +223,7 @@ type DropletCreateRequest struct {
|
|||
UserData string `json:"user_data,omitempty"`
|
||||
Volumes []DropletCreateVolume `json:"volumes,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
VPCUUID string `json:"vpc_uuid,omitempty"`
|
||||
}
|
||||
|
||||
// DropletMultiCreateRequest is a request to create multiple Droplets.
|
||||
|
@ -237,6 +239,7 @@ type DropletMultiCreateRequest struct {
|
|||
Monitoring bool `json:"monitoring"`
|
||||
UserData string `json:"user_data,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
VPCUUID string `json:"vpc_uuid,omitempty"`
|
||||
}
|
||||
|
||||
func (d DropletCreateRequest) String() string {
|
||||
|
|
|
@ -152,7 +152,8 @@ func TestDroplets_Create(t *testing.T) {
|
|||
{ID: "hello-im-another-volume"},
|
||||
{Name: "hello-im-still-a-volume", ID: "should be ignored due to Name"},
|
||||
},
|
||||
Tags: []string{"one", "two"},
|
||||
Tags: []string{"one", "two"},
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
}
|
||||
|
||||
mux.HandleFunc("/v2/droplets", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -171,8 +172,26 @@ func TestDroplets_Create(t *testing.T) {
|
|||
map[string]interface{}{"id": "hello-im-another-volume"},
|
||||
map[string]interface{}{"name": "hello-im-still-a-volume"},
|
||||
},
|
||||
"tags": []interface{}{"one", "two"},
|
||||
"tags": []interface{}{"one", "two"},
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
}
|
||||
jsonBlob := `
|
||||
{
|
||||
"droplet": {
|
||||
"id": 1,
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6"
|
||||
},
|
||||
"links": {
|
||||
"actions": [
|
||||
{
|
||||
"id": 1,
|
||||
"href": "http://example.com",
|
||||
"rel": "create"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var v map[string]interface{}
|
||||
err := json.NewDecoder(r.Body).Decode(&v)
|
||||
|
@ -184,7 +203,7 @@ func TestDroplets_Create(t *testing.T) {
|
|||
t.Errorf("Request body\n got=%#v\nwant=%#v", v, expected)
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, `{"droplet":{"id":1}, "links":{"actions": [{"id": 1, "href": "http://example.com", "rel": "create"}]}}`)
|
||||
fmt.Fprintf(w, jsonBlob)
|
||||
})
|
||||
|
||||
droplet, resp, err := client.Droplets.Create(ctx, createRequest)
|
||||
|
@ -196,6 +215,11 @@ func TestDroplets_Create(t *testing.T) {
|
|||
t.Errorf("expected id '%d', received '%d'", 1, id)
|
||||
}
|
||||
|
||||
vpcid := "880b7f98-f062-404d-b33c-458d545696f6"
|
||||
if id := droplet.VPCUUID; id != vpcid {
|
||||
t.Errorf("expected VPC uuid '%s', received '%s'", vpcid, id)
|
||||
}
|
||||
|
||||
if a := resp.Links.Actions[0]; a.ID != 1 {
|
||||
t.Errorf("expected action id '%d', received '%d'", 1, a.ID)
|
||||
}
|
||||
|
@ -212,7 +236,8 @@ func TestDroplets_CreateMultiple(t *testing.T) {
|
|||
Image: DropletCreateImage{
|
||||
ID: 1,
|
||||
},
|
||||
Tags: []string{"one", "two"},
|
||||
Tags: []string{"one", "two"},
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
}
|
||||
|
||||
mux.HandleFunc("/v2/droplets", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -227,7 +252,31 @@ func TestDroplets_CreateMultiple(t *testing.T) {
|
|||
"private_networking": false,
|
||||
"monitoring": false,
|
||||
"tags": []interface{}{"one", "two"},
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
}
|
||||
jsonBlob := `
|
||||
{
|
||||
"droplets": [
|
||||
{
|
||||
"id": 1,
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6"
|
||||
}
|
||||
],
|
||||
"links": {
|
||||
"actions": [
|
||||
{
|
||||
"id": 1,
|
||||
"href": "http://example.com",
|
||||
"rel": "multiple_create"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var v map[string]interface{}
|
||||
err := json.NewDecoder(r.Body).Decode(&v)
|
||||
|
@ -239,7 +288,7 @@ func TestDroplets_CreateMultiple(t *testing.T) {
|
|||
t.Errorf("Request body = %#v, expected %#v", v, expected)
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, `{"droplets":[{"id":1},{"id":2}], "links":{"actions": [{"id": 1, "href": "http://example.com", "rel": "multiple_create"}]}}`)
|
||||
fmt.Fprintf(w, jsonBlob)
|
||||
})
|
||||
|
||||
droplets, resp, err := client.Droplets.CreateMultiple(ctx, createRequest)
|
||||
|
@ -250,9 +299,16 @@ func TestDroplets_CreateMultiple(t *testing.T) {
|
|||
if id := droplets[0].ID; id != 1 {
|
||||
t.Errorf("expected id '%d', received '%d'", 1, id)
|
||||
}
|
||||
|
||||
if id := droplets[1].ID; id != 2 {
|
||||
t.Errorf("expected id '%d', received '%d'", 1, id)
|
||||
t.Errorf("expected id '%d', received '%d'", 2, id)
|
||||
}
|
||||
|
||||
vpcid := "880b7f98-f062-404d-b33c-458d545696f6"
|
||||
if id := droplets[0].VPCUUID; id != vpcid {
|
||||
t.Errorf("expected VPC uuid '%s', received '%s'", vpcid, id)
|
||||
}
|
||||
if id := droplets[1].VPCUUID; id != vpcid {
|
||||
t.Errorf("expected VPC uuid '%s', received '%s'", vpcid, id)
|
||||
}
|
||||
|
||||
if a := resp.Links.Actions[0]; a.ID != 1 {
|
||||
|
|
2
godo.go
2
godo.go
|
@ -66,6 +66,7 @@ type Client struct {
|
|||
Projects ProjectsService
|
||||
Kubernetes KubernetesService
|
||||
Databases DatabasesService
|
||||
VPCs VPCsService
|
||||
|
||||
// Optional function called after every successful request made to the DO APIs
|
||||
onRequestCompleted RequestCompletionCallback
|
||||
|
@ -181,6 +182,7 @@ func NewClient(httpClient *http.Client) *Client {
|
|||
c.Tags = &TagsServiceOp{client: c}
|
||||
c.Kubernetes = &KubernetesServiceOp{client: c}
|
||||
c.Databases = &DatabasesServiceOp{client: c}
|
||||
c.VPCs = &VPCsServiceOp{client: c}
|
||||
|
||||
return c
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ const (
|
|||
kubernetesOptionsPath = kubernetesBasePath + "/options"
|
||||
)
|
||||
|
||||
// KubernetesService is an interface for interfacing with the kubernetes endpoints
|
||||
// KubernetesService is an interface for interfacing with the Kubernetes endpoints
|
||||
// of the DigitalOcean API.
|
||||
// See: https://developers.digitalocean.com/documentation/v2#kubernetes
|
||||
type KubernetesService interface {
|
||||
|
@ -50,6 +50,7 @@ type KubernetesClusterCreateRequest struct {
|
|||
RegionSlug string `json:"region,omitempty"`
|
||||
VersionSlug string `json:"version,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
VPCUUID string `json:"vpc_uuid,omitempty"`
|
||||
|
||||
NodePools []*KubernetesNodePoolCreateRequest `json:"node_pools,omitempty"`
|
||||
}
|
||||
|
@ -94,6 +95,7 @@ type KubernetesCluster struct {
|
|||
IPv4 string `json:"ipv4,omitempty"`
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
VPCUUID string `json:"vpc_uuid,omitempty"`
|
||||
|
||||
NodePools []*KubernetesNodePool `json:"node_pools,omitempty"`
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ func TestKubernetesClusters_ListClusters(t *testing.T) {
|
|||
ServiceSubnet: "10.245.0.0/16",
|
||||
IPv4: "",
|
||||
Tags: []string(nil),
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
Status: &KubernetesClusterStatus{
|
||||
State: KubernetesClusterStatusRunning,
|
||||
},
|
||||
|
@ -64,6 +65,7 @@ func TestKubernetesClusters_ListClusters(t *testing.T) {
|
|||
ClusterSubnet: "10.244.0.0/16",
|
||||
ServiceSubnet: "10.245.0.0/16",
|
||||
IPv4: "1.2.3.4",
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f7",
|
||||
Status: &KubernetesClusterStatus{
|
||||
State: KubernetesClusterStatusRunning,
|
||||
},
|
||||
|
@ -107,6 +109,7 @@ func TestKubernetesClusters_ListClusters(t *testing.T) {
|
|||
"service_subnet": "10.245.0.0/16",
|
||||
"ipv4": "",
|
||||
"tags": null,
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
"status": {
|
||||
"state": "running"
|
||||
},
|
||||
|
@ -155,6 +158,7 @@ func TestKubernetesClusters_ListClusters(t *testing.T) {
|
|||
"status": {
|
||||
"state": "running"
|
||||
},
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f7",
|
||||
"node_pools": [
|
||||
{
|
||||
"id": "deadbeef-dead-beef-dead-deadbeefb4b3",
|
||||
|
@ -214,6 +218,7 @@ func TestKubernetesClusters_Get(t *testing.T) {
|
|||
ClusterSubnet: "10.244.0.0/16",
|
||||
ServiceSubnet: "10.245.0.0/16",
|
||||
IPv4: "1.2.3.4",
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
Status: &KubernetesClusterStatus{
|
||||
State: KubernetesClusterStatusRunning,
|
||||
},
|
||||
|
@ -255,6 +260,7 @@ func TestKubernetesClusters_Get(t *testing.T) {
|
|||
"service_subnet": "10.245.0.0/16",
|
||||
"ipv4": "1.2.3.4",
|
||||
"tags": null,
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
"status": {
|
||||
"state": "running"
|
||||
},
|
||||
|
@ -332,6 +338,7 @@ func TestKubernetesClusters_Create(t *testing.T) {
|
|||
ClusterSubnet: "10.244.0.0/16",
|
||||
ServiceSubnet: "10.245.0.0/16",
|
||||
Tags: []string{"cluster-tag-1", "cluster-tag-2"},
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
NodePools: []*KubernetesNodePool{
|
||||
&KubernetesNodePool{
|
||||
ID: "8d91899c-0739-4a1a-acc5-deadbeefbb8a",
|
||||
|
@ -347,6 +354,7 @@ func TestKubernetesClusters_Create(t *testing.T) {
|
|||
RegionSlug: want.RegionSlug,
|
||||
VersionSlug: want.VersionSlug,
|
||||
Tags: want.Tags,
|
||||
VPCUUID: want.VPCUUID,
|
||||
NodePools: []*KubernetesNodePoolCreateRequest{
|
||||
&KubernetesNodePoolCreateRequest{
|
||||
Size: want.NodePools[0].Size,
|
||||
|
@ -370,6 +378,7 @@ func TestKubernetesClusters_Create(t *testing.T) {
|
|||
"cluster-tag-1",
|
||||
"cluster-tag-2"
|
||||
],
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
"node_pools": [
|
||||
{
|
||||
"id": "8d91899c-0739-4a1a-acc5-deadbeefbb8a",
|
||||
|
@ -415,6 +424,7 @@ func TestKubernetesClusters_Update(t *testing.T) {
|
|||
ClusterSubnet: "10.244.0.0/16",
|
||||
ServiceSubnet: "10.245.0.0/16",
|
||||
Tags: []string{"cluster-tag-1", "cluster-tag-2"},
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
NodePools: []*KubernetesNodePool{
|
||||
&KubernetesNodePool{
|
||||
ID: "8d91899c-0739-4a1a-acc5-deadbeefbb8a",
|
||||
|
@ -443,6 +453,7 @@ func TestKubernetesClusters_Update(t *testing.T) {
|
|||
"cluster-tag-1",
|
||||
"cluster-tag-2"
|
||||
],
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
"node_pools": [
|
||||
{
|
||||
"id": "8d91899c-0739-4a1a-acc5-deadbeefbb8a",
|
||||
|
|
|
@ -43,6 +43,7 @@ type LoadBalancer struct {
|
|||
Tags []string `json:"tags,omitempty"`
|
||||
RedirectHttpToHttps bool `json:"redirect_http_to_https,omitempty"`
|
||||
EnableProxyProtocol bool `json:"enable_proxy_protocol,omitempty"`
|
||||
VPCUUID string `json:"vpc_uuid,omitempty"`
|
||||
}
|
||||
|
||||
// String creates a human-readable description of a LoadBalancer.
|
||||
|
@ -66,6 +67,7 @@ func (l LoadBalancer) AsRequest() *LoadBalancerRequest {
|
|||
RedirectHttpToHttps: l.RedirectHttpToHttps,
|
||||
EnableProxyProtocol: l.EnableProxyProtocol,
|
||||
HealthCheck: l.HealthCheck,
|
||||
VPCUUID: l.VPCUUID,
|
||||
}
|
||||
|
||||
if l.HealthCheck != nil {
|
||||
|
@ -138,6 +140,7 @@ type LoadBalancerRequest struct {
|
|||
Tags []string `json:"tags,omitempty"`
|
||||
RedirectHttpToHttps bool `json:"redirect_http_to_https,omitempty"`
|
||||
EnableProxyProtocol bool `json:"enable_proxy_protocol,omitempty"`
|
||||
VPCUUID string `json:"vpc_uuid,omitempty"`
|
||||
}
|
||||
|
||||
// String creates a human-readable description of a LoadBalancerRequest.
|
||||
|
|
|
@ -144,7 +144,8 @@ var lbCreateJSONResponse = `
|
|||
2,
|
||||
21
|
||||
],
|
||||
"redirect_http_to_https":true
|
||||
"redirect_http_to_https":true,
|
||||
"vpc_uuid":"880b7f98-f062-404d-b33c-458d545696f6"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
@ -369,6 +370,7 @@ func TestLoadBalancers_Create(t *testing.T) {
|
|||
Tags: []string{"my-tag"},
|
||||
DropletIDs: []int{2, 21},
|
||||
RedirectHttpToHttps: true,
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
}
|
||||
|
||||
path := "/v2/load_balancers"
|
||||
|
@ -438,6 +440,7 @@ func TestLoadBalancers_Create(t *testing.T) {
|
|||
Tags: []string{"my-tag"},
|
||||
DropletIDs: []int{2, 21},
|
||||
RedirectHttpToHttps: true,
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
}
|
||||
|
||||
assert.Equal(t, expected, loadBalancer)
|
||||
|
@ -825,6 +828,7 @@ func TestLoadBalancers_AsRequest(t *testing.T) {
|
|||
},
|
||||
RedirectHttpToHttps: true,
|
||||
EnableProxyProtocol: true,
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
}
|
||||
lb.DropletIDs = make([]int, 1, 2)
|
||||
lb.DropletIDs[0] = 12345
|
||||
|
@ -863,6 +867,7 @@ func TestLoadBalancers_AsRequest(t *testing.T) {
|
|||
DropletIDs: []int{12345},
|
||||
RedirectHttpToHttps: true,
|
||||
EnableProxyProtocol: true,
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
}
|
||||
|
||||
r := lb.AsRequest()
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
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"`
|
||||
}
|
||||
|
||||
// VPCUpdateRequest represents a request to update a Virtual Private Cloud.
|
||||
type VPCUpdateRequest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
// VPC represents a DigitalOcean Virtual Private Cloud configuration.
|
||||
type VPC struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,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"`
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
|
@ -0,0 +1,218 @@
|
|||
package godo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var vTestObj = &VPC{
|
||||
ID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
Name: "my-new-vpc",
|
||||
RegionSlug: "s2r7",
|
||||
CreatedAt: time.Date(2019, 2, 4, 21, 48, 40, 995304079, time.UTC),
|
||||
Default: false,
|
||||
}
|
||||
|
||||
var vTestJSON = `
|
||||
{
|
||||
"id":"880b7f98-f062-404d-b33c-458d545696f6",
|
||||
"name":"my-new-vpc",
|
||||
"region":"s2r7",
|
||||
"created_at":"2019-02-04T21:48:40.995304079Z",
|
||||
"default":false
|
||||
}
|
||||
`
|
||||
|
||||
func TestVPCs_Get(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
svc := client.VPCs
|
||||
path := "/v2/vpcs"
|
||||
want := vTestObj
|
||||
id := "880b7f98-f062-404d-b33c-458d545696f6"
|
||||
jsonBlob := `
|
||||
{
|
||||
"vpc":
|
||||
` + vTestJSON + `
|
||||
}
|
||||
`
|
||||
|
||||
mux.HandleFunc(path+"/"+id, func(w http.ResponseWriter, r *http.Request) {
|
||||
testMethod(t, r, http.MethodGet)
|
||||
fmt.Fprint(w, jsonBlob)
|
||||
})
|
||||
|
||||
got, _, err := svc.Get(ctx, id)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, want, got)
|
||||
}
|
||||
|
||||
func TestVPCs_List(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
svc := client.VPCs
|
||||
path := "/v2/vpcs"
|
||||
want := []*VPC{
|
||||
vTestObj,
|
||||
}
|
||||
links := &Links{
|
||||
Pages: &Pages{
|
||||
Last: "http://localhost/v2/vpcs?page=3&per_page=1",
|
||||
Next: "http://localhost/v2/vpcs?page=2&per_page=1",
|
||||
},
|
||||
}
|
||||
jsonBlob := `
|
||||
{
|
||||
"vpcs": [
|
||||
` + vTestJSON + `
|
||||
],
|
||||
"links": {
|
||||
"pages": {
|
||||
"last": "http://localhost/v2/vpcs?page=3&per_page=1",
|
||||
"next": "http://localhost/v2/vpcs?page=2&per_page=1"
|
||||
}
|
||||
},
|
||||
"meta": {"total": 3}
|
||||
}
|
||||
`
|
||||
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
|
||||
testMethod(t, r, http.MethodGet)
|
||||
fmt.Fprint(w, jsonBlob)
|
||||
})
|
||||
|
||||
got, resp, err := svc.List(ctx, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, want, got)
|
||||
require.Equal(t, resp.Links, links)
|
||||
}
|
||||
|
||||
func TestVPCs_Create(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
svc := client.VPCs
|
||||
path := "/v2/vpcs"
|
||||
want := vTestObj
|
||||
req := &VPCCreateRequest{
|
||||
Name: "my-new-vpc",
|
||||
RegionSlug: "s2r7",
|
||||
}
|
||||
jsonBlob := `
|
||||
{
|
||||
"vpc":
|
||||
` + vTestJSON + `
|
||||
}
|
||||
`
|
||||
|
||||
mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
|
||||
c := new(VPCCreateRequest)
|
||||
err := json.NewDecoder(r.Body).Decode(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testMethod(t, r, http.MethodPost)
|
||||
require.Equal(t, c, req)
|
||||
fmt.Fprint(w, jsonBlob)
|
||||
})
|
||||
|
||||
got, _, err := svc.Create(ctx, req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, want, got)
|
||||
}
|
||||
|
||||
func TestVPCs_Update(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
svc := client.VPCs
|
||||
path := "/v2/vpcs"
|
||||
want := vTestObj
|
||||
id := "880b7f98-f062-404d-b33c-458d545696f6"
|
||||
req := &VPCUpdateRequest{
|
||||
Name: "my-new-vpc",
|
||||
}
|
||||
jsonBlob := `
|
||||
{
|
||||
"vpc":
|
||||
` + vTestJSON + `
|
||||
}
|
||||
`
|
||||
|
||||
mux.HandleFunc(path+"/"+id, func(w http.ResponseWriter, r *http.Request) {
|
||||
c := new(VPCUpdateRequest)
|
||||
err := json.NewDecoder(r.Body).Decode(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testMethod(t, r, http.MethodPut)
|
||||
require.Equal(t, c, req)
|
||||
fmt.Fprint(w, jsonBlob)
|
||||
})
|
||||
|
||||
got, _, err := svc.Update(ctx, id, req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, want, got)
|
||||
}
|
||||
|
||||
func TestVPCs_Set(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
type setRequest struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
svc := client.VPCs
|
||||
path := "/v2/vpcs"
|
||||
want := vTestObj
|
||||
id := "880b7f98-f062-404d-b33c-458d545696f6"
|
||||
name := "my-new-vpc"
|
||||
req := &setRequest{Name: name}
|
||||
jsonBlob := `
|
||||
{
|
||||
"vpc":
|
||||
` + vTestJSON + `
|
||||
}
|
||||
`
|
||||
|
||||
mux.HandleFunc(path+"/"+id, func(w http.ResponseWriter, r *http.Request) {
|
||||
c := new(setRequest)
|
||||
err := json.NewDecoder(r.Body).Decode(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testMethod(t, r, http.MethodPatch)
|
||||
require.Equal(t, c, req)
|
||||
fmt.Fprint(w, jsonBlob)
|
||||
})
|
||||
|
||||
got, _, err := svc.Set(ctx, id, VPCSetName(name))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, want, got)
|
||||
}
|
||||
|
||||
func TestVPCs_Delete(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
svc := client.VPCs
|
||||
path := "/v2/vpcs"
|
||||
id := "880b7f98-f062-404d-b33c-458d545696f6"
|
||||
|
||||
mux.HandleFunc(path+"/"+id, func(w http.ResponseWriter, r *http.Request) {
|
||||
testMethod(t, r, http.MethodDelete)
|
||||
})
|
||||
|
||||
_, err := svc.Delete(ctx, id)
|
||||
require.NoError(t, err)
|
||||
}
|
Loading…
Reference in New Issue