Skip to content

Commit

Permalink
VPC: adds option to set a VPC as the regional default (digitalocean#401)
Browse files Browse the repository at this point in the history
* vpc: adds option for setting VPC as default VPC

* vpc: update vpcs.Update spec
  • Loading branch information
andrewloux authored Oct 26, 2020
1 parent d8d551d commit 48e3dce
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 62 deletions.
15 changes: 15 additions & 0 deletions vpcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type VPCCreateRequest struct {
type VPCUpdateRequest struct {
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
Default *bool `json:"default,omitempty"`
}

// VPCSetField allows one to set individual fields within a VPC configuration.
Expand All @@ -54,6 +55,16 @@ type VPCSetName string
// Ex.: VPCs.Set(..., VPCSetDescription("vpc description"))
type VPCSetDescription string

// 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{}

// VPC represents a DigitalOcean Virtual Private Cloud configuration.
type VPC struct {
ID string `json:"id,omitempty"`
Expand Down Expand Up @@ -161,6 +172,10 @@ func (n VPCSetDescription) vpcSetField(in map[string]interface{}) {
in["description"] = n
}

func (*vpcSetDefault) vpcSetField(in map[string]interface{}) {
in["default"] = true
}

// 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
Expand Down
211 changes: 149 additions & 62 deletions vpcs_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package godo

import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -140,82 +142,167 @@ func TestVPCs_Create(t *testing.T) {
}

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",
Description: "vpc description",
tests := []struct {
desc string
id string
req *VPCUpdateRequest
mockResponse string
expectedRequestBody string
expectedUpdatedVPC *VPC
}{
{
desc: "setting name and description without default argument",
id: "880b7f98-f062-404d-b33c-458d545696f6",
req: &VPCUpdateRequest{
Name: "my-new-vpc",
Description: "vpc description",
},
mockResponse: `
{
"vpc":
` + vTestJSON + `
}
`,
expectedRequestBody: `{"name":"my-new-vpc","description":"vpc description"}`,
expectedUpdatedVPC: vTestObj,
},

{
desc: "setting the default vpc option",
id: "880b7f98-f062-404d-b33c-458d545696f6",
req: &VPCUpdateRequest{
Name: "my-new-vpc",
Description: "vpc description",
Default: boolPtr(false),
},
mockResponse: `
{
"vpc":
` + vTestJSON + `
}
`,
expectedRequestBody: `{"name":"my-new-vpc","description":"vpc description","default":false}`,
expectedUpdatedVPC: vTestObj,
},

{
desc: "setting the default vpc option",
id: "880b7f98-f062-404d-b33c-458d545696f6",
req: &VPCUpdateRequest{
Name: "my-new-vpc",
Description: "vpc description",
Default: boolPtr(true),
},
mockResponse: `
{
"vpc":
` + vTestJSON + `
}
`,
expectedRequestBody: `{"name":"my-new-vpc","description":"vpc description","default":true}`,
expectedUpdatedVPC: vTestObj,
},
}
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)
}
for _, tt := range tests {
setup()

testMethod(t, r, http.MethodPut)
require.Equal(t, c, req)
fmt.Fprint(w, jsonBlob)
})
mux.HandleFunc("/v2/vpcs/"+tt.id, func(w http.ResponseWriter, r *http.Request) {
buf := new(bytes.Buffer)
buf.ReadFrom(r.Body)
require.Equal(t, tt.expectedRequestBody, strings.TrimSpace(buf.String()))

got, _, err := svc.Update(ctx, id, req)
require.NoError(t, err)
require.Equal(t, want, got)
v := new(VPCUpdateRequest)
err := json.NewDecoder(buf).Decode(v)
if err != nil {
t.Fatal(err)
}

testMethod(t, r, http.MethodPut)
fmt.Fprint(w, tt.mockResponse)
})

got, _, err := client.VPCs.Update(ctx, tt.id, tt.req)

teardown()

require.NoError(t, err)
require.Equal(t, tt.expectedUpdatedVPC, got)
}
}

func TestVPCs_Set(t *testing.T) {
setup()
defer teardown()

type setRequest struct {
Name string `json:"name"`
Description string `json:"description"`
}
tests := []struct {
desc string
id string
updateFields []VPCSetField
mockResponse string
expectedRequestBody string
expectedUpdatedVPC *VPC
}{
{
desc: "setting name and description",
id: "880b7f98-f062-404d-b33c-458d545696f6",
updateFields: []VPCSetField{
VPCSetName("my-new-vpc"),
VPCSetDescription("vpc description"),
},
mockResponse: `
{
"vpc":
` + vTestJSON + `
}
`,
expectedRequestBody: `{"description":"vpc description","name":"my-new-vpc"}`,
expectedUpdatedVPC: vTestObj,
},

svc := client.VPCs
path := "/v2/vpcs"
want := vTestObj
id := "880b7f98-f062-404d-b33c-458d545696f6"
name := "my-new-vpc"
desc := "vpc description"
req := &setRequest{
Name: name,
Description: desc,
{
desc: "setting the default vpc option",
id: "880b7f98-f062-404d-b33c-458d545696f6",
updateFields: []VPCSetField{
VPCSetName("my-new-vpc"),
VPCSetDescription("vpc description"),
VPCSetDefault(),
},
mockResponse: `
{
"vpc":
` + vTestJSON + `
}
`,
expectedRequestBody: `{"default":true,"description":"vpc description","name":"my-new-vpc"}`,
expectedUpdatedVPC: vTestObj,
},
}
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)
}
for _, tt := range tests {
setup()

testMethod(t, r, http.MethodPatch)
require.Equal(t, c, req)
fmt.Fprint(w, jsonBlob)
})
mux.HandleFunc("/v2/vpcs/"+tt.id, func(w http.ResponseWriter, r *http.Request) {
buf := new(bytes.Buffer)
buf.ReadFrom(r.Body)
require.Equal(t, tt.expectedRequestBody, strings.TrimSpace(buf.String()))

got, _, err := svc.Set(ctx, id, VPCSetName(name), VPCSetDescription(desc))
require.NoError(t, err)
require.Equal(t, want, got)
v := new(VPCUpdateRequest)
err := json.NewDecoder(buf).Decode(v)
if err != nil {
t.Fatal(err)
}

testMethod(t, r, http.MethodPatch)
fmt.Fprint(w, tt.mockResponse)
})

got, _, err := client.VPCs.Set(ctx, tt.id, tt.updateFields...)

teardown()

require.NoError(t, err)
require.Equal(t, tt.expectedUpdatedVPC, got)
}
}

func TestVPCs_Delete(t *testing.T) {
Expand Down

0 comments on commit 48e3dce

Please sign in to comment.