Add private networking configuration options to the Create request (#514)
During the create request, it will soon be possible to create droplets that have no public interface attached to them (droplets that only have a private interface). It will also be possible to attach a floating IP address to a droplet during the create proceess. This PR sets up the DropletCreateRequest fields to allow for that. Signed-off-by: Chris Cummer <ccummer@digitalocean.com>
This commit is contained in:
parent
922b629ace
commit
4e7d9fb21a
58
droplets.go
58
droplets.go
|
@ -216,37 +216,41 @@ func (d DropletCreateSSHKey) MarshalJSON() ([]byte, error) {
|
|||
|
||||
// DropletCreateRequest represents a request to create a Droplet.
|
||||
type DropletCreateRequest struct {
|
||||
Name string `json:"name"`
|
||||
Region string `json:"region"`
|
||||
Size string `json:"size"`
|
||||
Image DropletCreateImage `json:"image"`
|
||||
SSHKeys []DropletCreateSSHKey `json:"ssh_keys"`
|
||||
Backups bool `json:"backups"`
|
||||
IPv6 bool `json:"ipv6"`
|
||||
PrivateNetworking bool `json:"private_networking"`
|
||||
Monitoring bool `json:"monitoring"`
|
||||
UserData string `json:"user_data,omitempty"`
|
||||
Volumes []DropletCreateVolume `json:"volumes,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
VPCUUID string `json:"vpc_uuid,omitempty"`
|
||||
WithDropletAgent *bool `json:"with_droplet_agent,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Region string `json:"region"`
|
||||
Size string `json:"size"`
|
||||
Image DropletCreateImage `json:"image"`
|
||||
SSHKeys []DropletCreateSSHKey `json:"ssh_keys"`
|
||||
Backups bool `json:"backups"`
|
||||
IPv6 bool `json:"ipv6"`
|
||||
PrivateNetworking bool `json:"private_networking"`
|
||||
Monitoring bool `json:"monitoring"`
|
||||
UserData string `json:"user_data,omitempty"`
|
||||
Volumes []DropletCreateVolume `json:"volumes,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
VPCUUID string `json:"vpc_uuid,omitempty"`
|
||||
WithDropletAgent *bool `json:"with_droplet_agent,omitempty"`
|
||||
DisablePublicNetworking bool `json:"disable_public_networking,omitempty"`
|
||||
WithFloatingIPAddress bool `json:"with_floating_ip_address,omitempty"`
|
||||
}
|
||||
|
||||
// DropletMultiCreateRequest is a request to create multiple Droplets.
|
||||
type DropletMultiCreateRequest struct {
|
||||
Names []string `json:"names"`
|
||||
Region string `json:"region"`
|
||||
Size string `json:"size"`
|
||||
Image DropletCreateImage `json:"image"`
|
||||
SSHKeys []DropletCreateSSHKey `json:"ssh_keys"`
|
||||
Backups bool `json:"backups"`
|
||||
IPv6 bool `json:"ipv6"`
|
||||
PrivateNetworking bool `json:"private_networking"`
|
||||
Monitoring bool `json:"monitoring"`
|
||||
UserData string `json:"user_data,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
VPCUUID string `json:"vpc_uuid,omitempty"`
|
||||
WithDropletAgent *bool `json:"with_droplet_agent,omitempty"`
|
||||
Names []string `json:"names"`
|
||||
Region string `json:"region"`
|
||||
Size string `json:"size"`
|
||||
Image DropletCreateImage `json:"image"`
|
||||
SSHKeys []DropletCreateSSHKey `json:"ssh_keys"`
|
||||
Backups bool `json:"backups"`
|
||||
IPv6 bool `json:"ipv6"`
|
||||
PrivateNetworking bool `json:"private_networking"`
|
||||
Monitoring bool `json:"monitoring"`
|
||||
UserData string `json:"user_data,omitempty"`
|
||||
Tags []string `json:"tags"`
|
||||
VPCUUID string `json:"vpc_uuid,omitempty"`
|
||||
WithDropletAgent *bool `json:"with_droplet_agent,omitempty"`
|
||||
DisablePublicNetworking bool `json:"disable_public_networking,omitempty"`
|
||||
WithFloatingIPAddress bool `json:"with_floating_ip_address,omitempty"`
|
||||
}
|
||||
|
||||
func (d DropletCreateRequest) String() string {
|
||||
|
|
192
droplets_test.go
192
droplets_test.go
|
@ -377,6 +377,198 @@ func TestDroplets_WithDropletAgentJsonMarshal(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDroplets_CreateWithDisabledPublicNetworking(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
createRequest := &DropletCreateRequest{
|
||||
Name: "name",
|
||||
Region: "region",
|
||||
Size: "size",
|
||||
Image: DropletCreateImage{
|
||||
ID: 1,
|
||||
},
|
||||
Volumes: []DropletCreateVolume{
|
||||
{ID: "hello-im-another-volume"},
|
||||
{Name: "should be ignored due to Name", ID: "aaa-111-bbb-222-ccc"},
|
||||
},
|
||||
Tags: []string{"one", "two"},
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
DisablePublicNetworking: true,
|
||||
}
|
||||
|
||||
mux.HandleFunc("/v2/droplets", func(w http.ResponseWriter, r *http.Request) {
|
||||
expected := map[string]interface{}{
|
||||
"name": "name",
|
||||
"region": "region",
|
||||
"size": "size",
|
||||
"image": float64(1),
|
||||
"ssh_keys": nil,
|
||||
"backups": false,
|
||||
"ipv6": false,
|
||||
"private_networking": false,
|
||||
"monitoring": false,
|
||||
"volumes": []interface{}{
|
||||
map[string]interface{}{"id": "hello-im-another-volume"},
|
||||
map[string]interface{}{"id": "aaa-111-bbb-222-ccc"},
|
||||
},
|
||||
"tags": []interface{}{"one", "two"},
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
"disable_public_networking": true,
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
t.Fatalf("decode json: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(v, expected) {
|
||||
t.Errorf("Request body\n got=%#v\nwant=%#v", v, expected)
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, jsonBlob)
|
||||
})
|
||||
|
||||
droplet, _, err := client.Droplets.Create(ctx, createRequest)
|
||||
if err != nil {
|
||||
t.Errorf("Droplets.Create returned error: %v", err)
|
||||
}
|
||||
|
||||
if id := droplet.ID; id != 1 {
|
||||
t.Errorf("expected id '%d', received '%d'", 1, id)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDroplets_CreateWithFloatingIPAddress(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
createRequest := &DropletCreateRequest{
|
||||
Name: "name",
|
||||
Region: "region",
|
||||
Size: "size",
|
||||
Image: DropletCreateImage{
|
||||
ID: 1,
|
||||
},
|
||||
Volumes: []DropletCreateVolume{
|
||||
{ID: "hello-im-another-volume"},
|
||||
{Name: "should be ignored due to Name", ID: "aaa-111-bbb-222-ccc"},
|
||||
},
|
||||
Tags: []string{"one", "two"},
|
||||
VPCUUID: "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
WithFloatingIPAddress: true,
|
||||
}
|
||||
|
||||
mux.HandleFunc("/v2/droplets", func(w http.ResponseWriter, r *http.Request) {
|
||||
expected := map[string]interface{}{
|
||||
"name": "name",
|
||||
"region": "region",
|
||||
"size": "size",
|
||||
"image": float64(1),
|
||||
"ssh_keys": nil,
|
||||
"backups": false,
|
||||
"ipv6": false,
|
||||
"private_networking": false,
|
||||
"monitoring": false,
|
||||
"volumes": []interface{}{
|
||||
map[string]interface{}{"id": "hello-im-another-volume"},
|
||||
map[string]interface{}{"id": "aaa-111-bbb-222-ccc"},
|
||||
},
|
||||
"tags": []interface{}{"one", "two"},
|
||||
"vpc_uuid": "880b7f98-f062-404d-b33c-458d545696f6",
|
||||
"with_floating_ip_address": true,
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
t.Fatalf("decode json: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(v, expected) {
|
||||
t.Errorf("Request body\n got=%#v\nwant=%#v", v, expected)
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, jsonBlob)
|
||||
})
|
||||
|
||||
droplet, _, err := client.Droplets.Create(ctx, createRequest)
|
||||
if err != nil {
|
||||
t.Errorf("Droplets.Create returned error: %v", err)
|
||||
}
|
||||
|
||||
if id := droplet.ID; id != 1 {
|
||||
t.Errorf("expected id '%d', received '%d'", 1, id)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDroplet_PrivateNetworkingJsonMarshal(t *testing.T) {
|
||||
tests := []struct {
|
||||
in *DropletCreateRequest
|
||||
want string
|
||||
}{
|
||||
{
|
||||
in: &DropletCreateRequest{Name: "foo"},
|
||||
want: `{"name":"foo","region":"","size":"","image":0,"ssh_keys":null,"backups":false,"ipv6":false,"private_networking":false,"monitoring":false,"tags":null}`,
|
||||
},
|
||||
{
|
||||
in: &DropletCreateRequest{Name: "foo", DisablePublicNetworking: false, WithFloatingIPAddress: false},
|
||||
want: `{"name":"foo","region":"","size":"","image":0,"ssh_keys":null,"backups":false,"ipv6":false,"private_networking":false,"monitoring":false,"tags":null}`,
|
||||
},
|
||||
{
|
||||
in: &DropletCreateRequest{Name: "foo", DisablePublicNetworking: true, WithFloatingIPAddress: true},
|
||||
want: `{"name":"foo","region":"","size":"","image":0,"ssh_keys":null,"backups":false,"ipv6":false,"private_networking":false,"monitoring":false,"tags":null,"disable_public_networking":true,"with_floating_ip_address":true}`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
got, err := json.Marshal(tt.in)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("error: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(tt.want, string(got)) {
|
||||
t.Errorf("\nexpected: %v\n, got: %v", tt.want, string(got))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDroplets_CreateMultiple(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
|
56
godo_test.go
56
godo_test.go
|
@ -276,6 +276,62 @@ func TestNewRequest_withDropletAgent(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNewRequest_DisablePublicNetworking(t *testing.T) {
|
||||
c := NewClient(nil)
|
||||
|
||||
inURL, outURL := "/foo", defaultBaseURL+"foo"
|
||||
inBody, outBody := &DropletCreateRequest{Name: "l", DisablePublicNetworking: true},
|
||||
`{"name":"l","region":"","size":"","image":0,`+
|
||||
`"ssh_keys":null,"backups":false,"ipv6":false,`+
|
||||
`"private_networking":false,"monitoring":false,"tags":null,"disable_public_networking":true}`+"\n"
|
||||
req, _ := c.NewRequest(ctx, http.MethodPost, inURL, inBody)
|
||||
|
||||
// test relative URL was expanded
|
||||
if req.URL.String() != outURL {
|
||||
t.Errorf("NewRequest(%v) URL = %v, expected %v", inURL, req.URL, outURL)
|
||||
}
|
||||
|
||||
// test body was JSON encoded
|
||||
body, _ := ioutil.ReadAll(req.Body)
|
||||
if string(body) != outBody {
|
||||
t.Errorf("NewRequest(%v)Body = %v, expected %v", inBody, string(body), outBody)
|
||||
}
|
||||
|
||||
// test default user-agent is attached to the request
|
||||
userAgent := req.Header.Get("User-Agent")
|
||||
if c.UserAgent != userAgent {
|
||||
t.Errorf("NewRequest() User-Agent = %v, expected %v", userAgent, c.UserAgent)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewRequest_WithFLoatingIPAddress(t *testing.T) {
|
||||
c := NewClient(nil)
|
||||
|
||||
inURL, outURL := "/foo", defaultBaseURL+"foo"
|
||||
inBody, outBody := &DropletCreateRequest{Name: "l", WithFloatingIPAddress: true},
|
||||
`{"name":"l","region":"","size":"","image":0,`+
|
||||
`"ssh_keys":null,"backups":false,"ipv6":false,`+
|
||||
`"private_networking":false,"monitoring":false,"tags":null,"with_floating_ip_address":true}`+"\n"
|
||||
req, _ := c.NewRequest(ctx, http.MethodPost, inURL, inBody)
|
||||
|
||||
// test relative URL was expanded
|
||||
if req.URL.String() != outURL {
|
||||
t.Errorf("NewRequest(%v) URL = %v, expected %v", inURL, req.URL, outURL)
|
||||
}
|
||||
|
||||
// test body was JSON encoded
|
||||
body, _ := ioutil.ReadAll(req.Body)
|
||||
if string(body) != outBody {
|
||||
t.Errorf("NewRequest(%v)Body = %v, expected %v", inBody, string(body), outBody)
|
||||
}
|
||||
|
||||
// test default user-agent is attached to the request
|
||||
userAgent := req.Header.Get("User-Agent")
|
||||
if c.UserAgent != userAgent {
|
||||
t.Errorf("NewRequest() User-Agent = %v, expected %v", userAgent, c.UserAgent)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewRequest_badURL(t *testing.T) {
|
||||
c := NewClient(nil)
|
||||
_, err := c.NewRequest(ctx, http.MethodGet, ":", nil)
|
||||
|
|
Loading…
Reference in New Issue