1// +build acceptance networking
2
3package v2
4
5import (
6	"fmt"
7	"strings"
8	"testing"
9
10	"github.com/gophercloud/gophercloud/acceptance/clients"
11	subnetpools "github.com/gophercloud/gophercloud/acceptance/openstack/networking/v2/extensions/subnetpools"
12	"github.com/gophercloud/gophercloud/acceptance/tools"
13	"github.com/gophercloud/gophercloud/openstack/networking/v2/subnets"
14	th "github.com/gophercloud/gophercloud/testhelper"
15)
16
17func TestSubnetCRUD(t *testing.T) {
18	client, err := clients.NewNetworkV2Client()
19	th.AssertNoErr(t, err)
20
21	// Create Network
22	network, err := CreateNetwork(t, client)
23	th.AssertNoErr(t, err)
24	defer DeleteNetwork(t, client, network.ID)
25
26	// Create Subnet
27	subnet, err := CreateSubnet(t, client, network.ID)
28	th.AssertNoErr(t, err)
29	defer DeleteSubnet(t, client, subnet.ID)
30
31	tools.PrintResource(t, subnet)
32
33	// Update Subnet
34	newSubnetName := tools.RandomString("TESTACC-", 8)
35	newSubnetDescription := ""
36	updateOpts := subnets.UpdateOpts{
37		Name:        &newSubnetName,
38		Description: &newSubnetDescription,
39	}
40	_, err = subnets.Update(client, subnet.ID, updateOpts).Extract()
41	th.AssertNoErr(t, err)
42
43	// Get subnet
44	newSubnet, err := subnets.Get(client, subnet.ID).Extract()
45	th.AssertNoErr(t, err)
46
47	tools.PrintResource(t, newSubnet)
48	th.AssertEquals(t, newSubnet.Name, newSubnetName)
49	th.AssertEquals(t, newSubnet.Description, newSubnetDescription)
50
51	allPages, err := subnets.List(client, nil).AllPages()
52	th.AssertNoErr(t, err)
53
54	allSubnets, err := subnets.ExtractSubnets(allPages)
55	th.AssertNoErr(t, err)
56
57	var found bool
58	for _, subnet := range allSubnets {
59		if subnet.ID == newSubnet.ID {
60			found = true
61		}
62	}
63
64	th.AssertEquals(t, found, true)
65}
66
67func TestSubnetsDefaultGateway(t *testing.T) {
68	client, err := clients.NewNetworkV2Client()
69	th.AssertNoErr(t, err)
70
71	// Create Network
72	network, err := CreateNetwork(t, client)
73	th.AssertNoErr(t, err)
74	defer DeleteNetwork(t, client, network.ID)
75
76	// Create Subnet
77	subnet, err := CreateSubnetWithDefaultGateway(t, client, network.ID)
78	th.AssertNoErr(t, err)
79	defer DeleteSubnet(t, client, subnet.ID)
80
81	tools.PrintResource(t, subnet)
82
83	if subnet.GatewayIP == "" {
84		t.Fatalf("A default gateway was not created.")
85	}
86
87	var noGateway = ""
88	updateOpts := subnets.UpdateOpts{
89		GatewayIP: &noGateway,
90	}
91
92	newSubnet, err := subnets.Update(client, subnet.ID, updateOpts).Extract()
93	th.AssertNoErr(t, err)
94
95	if newSubnet.GatewayIP != "" {
96		t.Fatalf("Gateway was not updated correctly")
97	}
98}
99
100func TestSubnetsNoGateway(t *testing.T) {
101	client, err := clients.NewNetworkV2Client()
102	th.AssertNoErr(t, err)
103
104	// Create Network
105	network, err := CreateNetwork(t, client)
106	th.AssertNoErr(t, err)
107	defer DeleteNetwork(t, client, network.ID)
108
109	// Create Subnet
110	subnet, err := CreateSubnetWithNoGateway(t, client, network.ID)
111	th.AssertNoErr(t, err)
112	defer DeleteSubnet(t, client, subnet.ID)
113
114	tools.PrintResource(t, subnet)
115
116	if subnet.GatewayIP != "" {
117		t.Fatalf("A gateway exists when it shouldn't.")
118	}
119
120	subnetParts := strings.Split(subnet.CIDR, ".")
121	newGateway := fmt.Sprintf("%s.%s.%s.1", subnetParts[0], subnetParts[1], subnetParts[2])
122	updateOpts := subnets.UpdateOpts{
123		GatewayIP: &newGateway,
124	}
125
126	newSubnet, err := subnets.Update(client, subnet.ID, updateOpts).Extract()
127	th.AssertNoErr(t, err)
128
129	if newSubnet.GatewayIP == "" {
130		t.Fatalf("Gateway was not updated correctly")
131	}
132}
133
134func TestSubnetsWithSubnetPool(t *testing.T) {
135	client, err := clients.NewNetworkV2Client()
136	th.AssertNoErr(t, err)
137
138	// Create Network
139	network, err := CreateNetwork(t, client)
140	th.AssertNoErr(t, err)
141	defer DeleteNetwork(t, client, network.ID)
142
143	// Create SubnetPool
144	subnetPool, err := subnetpools.CreateSubnetPool(t, client)
145	th.AssertNoErr(t, err)
146	defer subnetpools.DeleteSubnetPool(t, client, subnetPool.ID)
147
148	// Create Subnet
149	subnet, err := CreateSubnetWithSubnetPool(t, client, network.ID, subnetPool.ID)
150	th.AssertNoErr(t, err)
151	defer DeleteSubnet(t, client, subnet.ID)
152
153	tools.PrintResource(t, subnet)
154
155	if subnet.GatewayIP == "" {
156		t.Fatalf("A subnet pool was not associated.")
157	}
158}
159
160func TestSubnetsWithSubnetPoolNoCIDR(t *testing.T) {
161	client, err := clients.NewNetworkV2Client()
162	th.AssertNoErr(t, err)
163
164	// Create Network
165	network, err := CreateNetwork(t, client)
166	th.AssertNoErr(t, err)
167	defer DeleteNetwork(t, client, network.ID)
168
169	// Create SubnetPool
170	subnetPool, err := subnetpools.CreateSubnetPool(t, client)
171	th.AssertNoErr(t, err)
172	defer subnetpools.DeleteSubnetPool(t, client, subnetPool.ID)
173
174	// Create Subnet
175	subnet, err := CreateSubnetWithSubnetPoolNoCIDR(t, client, network.ID, subnetPool.ID)
176	th.AssertNoErr(t, err)
177	defer DeleteSubnet(t, client, subnet.ID)
178
179	tools.PrintResource(t, subnet)
180
181	if subnet.GatewayIP == "" {
182		t.Fatalf("A subnet pool was not associated.")
183	}
184}
185
186func TestSubnetsWithSubnetPoolPrefixlen(t *testing.T) {
187	client, err := clients.NewNetworkV2Client()
188	th.AssertNoErr(t, err)
189
190	// Create Network
191	network, err := CreateNetwork(t, client)
192	th.AssertNoErr(t, err)
193	defer DeleteNetwork(t, client, network.ID)
194
195	// Create SubnetPool
196	subnetPool, err := subnetpools.CreateSubnetPool(t, client)
197	th.AssertNoErr(t, err)
198	defer subnetpools.DeleteSubnetPool(t, client, subnetPool.ID)
199
200	// Create Subnet
201	subnet, err := CreateSubnetWithSubnetPoolPrefixlen(t, client, network.ID, subnetPool.ID)
202	th.AssertNoErr(t, err)
203	defer DeleteSubnet(t, client, subnet.ID)
204
205	tools.PrintResource(t, subnet)
206
207	if subnet.GatewayIP == "" {
208		t.Fatalf("A subnet pool was not associated.")
209	}
210
211	cidrParts := strings.Split(subnet.CIDR, "/")
212	if len(cidrParts) != 2 {
213		t.Fatalf("Got invalid CIDR for subnet '%s': %s", subnet.ID, subnet.CIDR)
214	}
215
216	if cidrParts[1] != "12" {
217		t.Fatalf("Got invalid prefix length for subnet '%s': wanted 12 but got '%s'", subnet.ID, cidrParts[1])
218	}
219}
220
221func TestSubnetDNSNameservers(t *testing.T) {
222	client, err := clients.NewNetworkV2Client()
223	th.AssertNoErr(t, err)
224
225	// Create Network
226	network, err := CreateNetwork(t, client)
227	th.AssertNoErr(t, err)
228	defer DeleteNetwork(t, client, network.ID)
229
230	// Create Subnet
231	subnet, err := CreateSubnet(t, client, network.ID)
232	th.AssertNoErr(t, err)
233	defer DeleteSubnet(t, client, subnet.ID)
234
235	tools.PrintResource(t, subnet)
236
237	// Update Subnet
238	dnsNameservers := []string{"1.1.1.1"}
239	updateOpts := subnets.UpdateOpts{
240		DNSNameservers: &dnsNameservers,
241	}
242	_, err = subnets.Update(client, subnet.ID, updateOpts).Extract()
243	th.AssertNoErr(t, err)
244
245	// Get subnet
246	newSubnet, err := subnets.Get(client, subnet.ID).Extract()
247	th.AssertNoErr(t, err)
248
249	tools.PrintResource(t, newSubnet)
250	th.AssertEquals(t, len(newSubnet.DNSNameservers), 1)
251
252	// Update Subnet again
253	dnsNameservers = []string{}
254	updateOpts = subnets.UpdateOpts{
255		DNSNameservers: &dnsNameservers,
256	}
257	_, err = subnets.Update(client, subnet.ID, updateOpts).Extract()
258	th.AssertNoErr(t, err)
259
260	// Get subnet
261	newSubnet, err = subnets.Get(client, subnet.ID).Extract()
262	th.AssertNoErr(t, err)
263
264	tools.PrintResource(t, newSubnet)
265	th.AssertEquals(t, len(newSubnet.DNSNameservers), 0)
266}
267