Skip to content
This repository was archived by the owner on Aug 1, 2023. It is now read-only.

Commit f92ae6c

Browse files
committed
Allow subnets to have no gateway
1 parent 61270d4 commit f92ae6c

File tree

3 files changed

+168
-2
lines changed

3 files changed

+168
-2
lines changed

acceptance/openstack/networking/v2/subnet_test.go

+41-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
th "github.com/rackspace/gophercloud/testhelper"
1212
)
1313

14-
func TestList(t *testing.T) {
14+
func TestSubnetList(t *testing.T) {
1515
Setup(t)
1616
defer Teardown()
1717

@@ -32,7 +32,7 @@ func TestList(t *testing.T) {
3232
th.CheckNoErr(t, err)
3333
}
3434

35-
func TestCRUD(t *testing.T) {
35+
func TestSubnetCRUD(t *testing.T) {
3636
Setup(t)
3737
defer Teardown()
3838

@@ -61,6 +61,7 @@ func TestCRUD(t *testing.T) {
6161
th.AssertEquals(t, s.IPVersion, 4)
6262
th.AssertEquals(t, s.Name, "my_subnet")
6363
th.AssertEquals(t, s.EnableDHCP, false)
64+
th.AssertEquals(t, s.GatewayIP, "192.168.199.1")
6465
subnetID := s.ID
6566

6667
// Get subnet
@@ -79,6 +80,44 @@ func TestCRUD(t *testing.T) {
7980
t.Log("Delete subnet")
8081
res := subnets.Delete(Client, subnetID)
8182
th.AssertNoErr(t, res.Err)
83+
84+
// Create subnet with no gateway
85+
t.Log("Create subnet with no gateway")
86+
opts = subnets.CreateOpts{
87+
NetworkID: networkID,
88+
CIDR: "192.168.199.0/24",
89+
IPVersion: subnets.IPv4,
90+
Name: "my_subnet",
91+
EnableDHCP: &enable,
92+
NoGateway: true,
93+
}
94+
s, err = subnets.Create(Client, opts).Extract()
95+
th.AssertNoErr(t, err)
96+
97+
th.AssertEquals(t, s.NetworkID, networkID)
98+
th.AssertEquals(t, s.CIDR, "192.168.199.0/24")
99+
th.AssertEquals(t, s.IPVersion, 4)
100+
th.AssertEquals(t, s.Name, "my_subnet")
101+
th.AssertEquals(t, s.EnableDHCP, false)
102+
th.AssertEquals(t, s.GatewayIP, "")
103+
subnetID = s.ID
104+
105+
// Get subnet
106+
t.Log("Getting subnet with no gateway")
107+
s, err = subnets.Get(Client, subnetID).Extract()
108+
th.AssertNoErr(t, err)
109+
th.AssertEquals(t, s.ID, subnetID)
110+
111+
// Update subnet
112+
t.Log("Update subnet with no gateway")
113+
s, err = subnets.Update(Client, subnetID, subnets.UpdateOpts{Name: "new_subnet_name"}).Extract()
114+
th.AssertNoErr(t, err)
115+
th.AssertEquals(t, s.Name, "new_subnet_name")
116+
117+
// Delete subnet
118+
t.Log("Delete subnet with no gateway")
119+
res = subnets.Delete(Client, subnetID)
120+
th.AssertNoErr(t, res.Err)
82121
}
83122

84123
func TestBatchCreate(t *testing.T) {

openstack/networking/v2/subnets/requests.go

+6
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ type CreateOpts struct {
108108
TenantID string
109109
AllocationPools []AllocationPool
110110
GatewayIP string
111+
NoGateway bool
111112
IPVersion int
112113
EnableDHCP *bool
113114
DNSNameservers []string
@@ -139,6 +140,8 @@ func (opts CreateOpts) ToSubnetCreateMap() (map[string]interface{}, error) {
139140
}
140141
if opts.GatewayIP != "" {
141142
s["gateway_ip"] = opts.GatewayIP
143+
} else if opts.NoGateway {
144+
s["gateway_ip"] = nil
142145
}
143146
if opts.TenantID != "" {
144147
s["tenant_id"] = opts.TenantID
@@ -184,6 +187,7 @@ type UpdateOptsBuilder interface {
184187
type UpdateOpts struct {
185188
Name string
186189
GatewayIP string
190+
NoGateway bool
187191
DNSNameservers []string
188192
HostRoutes []HostRoute
189193
EnableDHCP *bool
@@ -201,6 +205,8 @@ func (opts UpdateOpts) ToSubnetUpdateMap() (map[string]interface{}, error) {
201205
}
202206
if opts.GatewayIP != "" {
203207
s["gateway_ip"] = opts.GatewayIP
208+
} else if opts.NoGateway {
209+
s["gateway_ip"] = nil
204210
}
205211
if opts.DNSNameservers != nil {
206212
s["dns_nameservers"] = opts.DNSNameservers

openstack/networking/v2/subnets/requests_test.go

+121
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,24 @@ func TestList(t *testing.T) {
5959
"gateway_ip": "192.0.0.1",
6060
"cidr": "192.0.0.0/8",
6161
"id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b"
62+
},
63+
{
64+
"name": "my_gatewayless_subnet",
65+
"enable_dhcp": true,
66+
"network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23",
67+
"tenant_id": "4fd44f30292945e481c7b8a0c8908869",
68+
"dns_nameservers": [],
69+
"allocation_pools": [
70+
{
71+
"start": "192.168.1.2",
72+
"end": "192.168.1.254"
73+
}
74+
],
75+
"host_routes": [],
76+
"ip_version": 4,
77+
"gateway_ip": null,
78+
"cidr": "192.168.1.0/24",
79+
"id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0c"
6280
}
6381
]
6482
}
@@ -112,6 +130,24 @@ func TestList(t *testing.T) {
112130
CIDR: "192.0.0.0/8",
113131
ID: "54d6f61d-db07-451c-9ab3-b9609b6b6f0b",
114132
},
133+
Subnet{
134+
Name: "my_gatewayless_subnet",
135+
EnableDHCP: true,
136+
NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23",
137+
TenantID: "4fd44f30292945e481c7b8a0c8908869",
138+
DNSNameservers: []string{},
139+
AllocationPools: []AllocationPool{
140+
AllocationPool{
141+
Start: "192.168.1.2",
142+
End: "192.168.1.254",
143+
},
144+
},
145+
HostRoutes: []HostRoute{},
146+
IPVersion: 4,
147+
GatewayIP: "",
148+
CIDR: "192.168.1.0/24",
149+
ID: "54d6f61d-db07-451c-9ab3-b9609b6b6f0c",
150+
},
115151
}
116152

117153
th.CheckDeepEquals(t, expected, actual)
@@ -270,6 +306,91 @@ func TestCreate(t *testing.T) {
270306
th.AssertEquals(t, s.ID, "3b80198d-4f7b-4f77-9ef5-774d54e17126")
271307
}
272308

309+
func TestCreateNoGateway(t *testing.T) {
310+
th.SetupHTTP()
311+
defer th.TeardownHTTP()
312+
313+
th.Mux.HandleFunc("/v2.0/subnets", func(w http.ResponseWriter, r *http.Request) {
314+
th.TestMethod(t, r, "POST")
315+
th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
316+
th.TestHeader(t, r, "Content-Type", "application/json")
317+
th.TestHeader(t, r, "Accept", "application/json")
318+
th.TestJSONRequest(t, r, `
319+
{
320+
"subnet": {
321+
"network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23",
322+
"ip_version": 4,
323+
"cidr": "192.168.1.0/24",
324+
"gateway_ip": null,
325+
"allocation_pools": [
326+
{
327+
"start": "192.168.1.2",
328+
"end": "192.168.1.254"
329+
}
330+
]
331+
}
332+
}
333+
`)
334+
335+
w.Header().Add("Content-Type", "application/json")
336+
w.WriteHeader(http.StatusCreated)
337+
338+
fmt.Fprintf(w, `
339+
{
340+
"subnet": {
341+
"name": "",
342+
"enable_dhcp": true,
343+
"network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a23",
344+
"tenant_id": "4fd44f30292945e481c7b8a0c8908869",
345+
"allocation_pools": [
346+
{
347+
"start": "192.168.1.2",
348+
"end": "192.168.1.254"
349+
}
350+
],
351+
"host_routes": [],
352+
"ip_version": 4,
353+
"gateway_ip": null,
354+
"cidr": "192.168.1.0/24",
355+
"id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0c"
356+
}
357+
}
358+
`)
359+
})
360+
361+
opts := CreateOpts{
362+
NetworkID: "d32019d3-bc6e-4319-9c1d-6722fc136a23",
363+
IPVersion: 4,
364+
CIDR: "192.168.1.0/24",
365+
NoGateway: true,
366+
AllocationPools: []AllocationPool{
367+
AllocationPool{
368+
Start: "192.168.1.2",
369+
End: "192.168.1.254",
370+
},
371+
},
372+
DNSNameservers: []string{},
373+
}
374+
s, err := Create(fake.ServiceClient(), opts).Extract()
375+
th.AssertNoErr(t, err)
376+
377+
th.AssertEquals(t, s.Name, "")
378+
th.AssertEquals(t, s.EnableDHCP, true)
379+
th.AssertEquals(t, s.NetworkID, "d32019d3-bc6e-4319-9c1d-6722fc136a23")
380+
th.AssertEquals(t, s.TenantID, "4fd44f30292945e481c7b8a0c8908869")
381+
th.AssertDeepEquals(t, s.AllocationPools, []AllocationPool{
382+
AllocationPool{
383+
Start: "192.168.1.2",
384+
End: "192.168.1.254",
385+
},
386+
})
387+
th.AssertDeepEquals(t, s.HostRoutes, []HostRoute{})
388+
th.AssertEquals(t, s.IPVersion, 4)
389+
th.AssertEquals(t, s.GatewayIP, "")
390+
th.AssertEquals(t, s.CIDR, "192.168.1.0/24")
391+
th.AssertEquals(t, s.ID, "54d6f61d-db07-451c-9ab3-b9609b6b6f0c")
392+
}
393+
273394
func TestRequiredCreateOpts(t *testing.T) {
274395
res := Create(fake.ServiceClient(), CreateOpts{})
275396
if res.Err == nil {

0 commit comments

Comments
 (0)