github.com/gophercloud/gophercloud@v1.11.0/internal/acceptance/openstack/networking/v2/subnets_test.go (about) 1 //go:build acceptance || networking 2 // +build acceptance networking 3 4 package v2 5 6 import ( 7 "fmt" 8 "strings" 9 "testing" 10 11 "github.com/gophercloud/gophercloud/internal/acceptance/clients" 12 subnetpools "github.com/gophercloud/gophercloud/internal/acceptance/openstack/networking/v2/extensions/subnetpools" 13 "github.com/gophercloud/gophercloud/internal/acceptance/tools" 14 "github.com/gophercloud/gophercloud/openstack/networking/v2/subnets" 15 th "github.com/gophercloud/gophercloud/testhelper" 16 ) 17 18 func TestSubnetCRUD(t *testing.T) { 19 client, err := clients.NewNetworkV2Client() 20 th.AssertNoErr(t, err) 21 22 // Create Network 23 network, err := CreateNetwork(t, client) 24 th.AssertNoErr(t, err) 25 defer DeleteNetwork(t, client, network.ID) 26 27 // Create Subnet 28 subnet, err := CreateSubnet(t, client, network.ID) 29 th.AssertNoErr(t, err) 30 defer DeleteSubnet(t, client, subnet.ID) 31 32 tools.PrintResource(t, subnet) 33 34 // Update Subnet 35 newSubnetName := tools.RandomString("TESTACC-", 8) 36 newSubnetDescription := "" 37 updateOpts := subnets.UpdateOpts{ 38 Name: &newSubnetName, 39 Description: &newSubnetDescription, 40 } 41 _, err = subnets.Update(client, subnet.ID, updateOpts).Extract() 42 th.AssertNoErr(t, err) 43 44 // Get subnet 45 newSubnet, err := subnets.Get(client, subnet.ID).Extract() 46 th.AssertNoErr(t, err) 47 48 tools.PrintResource(t, newSubnet) 49 th.AssertEquals(t, newSubnet.Name, newSubnetName) 50 th.AssertEquals(t, newSubnet.Description, newSubnetDescription) 51 52 allPages, err := subnets.List(client, nil).AllPages() 53 th.AssertNoErr(t, err) 54 55 allSubnets, err := subnets.ExtractSubnets(allPages) 56 th.AssertNoErr(t, err) 57 58 var found bool 59 for _, subnet := range allSubnets { 60 if subnet.ID == newSubnet.ID { 61 found = true 62 } 63 } 64 65 th.AssertEquals(t, found, true) 66 } 67 68 func TestSubnetsServiceType(t *testing.T) { 69 client, err := clients.NewNetworkV2Client() 70 th.AssertNoErr(t, err) 71 72 // Create Network 73 network, err := CreateNetwork(t, client) 74 th.AssertNoErr(t, err) 75 defer DeleteNetwork(t, client, network.ID) 76 77 // Create Subnet 78 subnet, err := CreateSubnetWithServiceTypes(t, client, network.ID) 79 th.AssertNoErr(t, err) 80 defer DeleteSubnet(t, client, subnet.ID) 81 82 tools.PrintResource(t, subnet) 83 84 serviceTypes := []string{"network:floatingip"} 85 updateOpts := subnets.UpdateOpts{ 86 ServiceTypes: &serviceTypes, 87 } 88 89 newSubnet, err := subnets.Update(client, subnet.ID, updateOpts).Extract() 90 th.AssertNoErr(t, err) 91 92 th.AssertDeepEquals(t, newSubnet.ServiceTypes, serviceTypes) 93 } 94 95 func TestSubnetsDefaultGateway(t *testing.T) { 96 client, err := clients.NewNetworkV2Client() 97 th.AssertNoErr(t, err) 98 99 // Create Network 100 network, err := CreateNetwork(t, client) 101 th.AssertNoErr(t, err) 102 defer DeleteNetwork(t, client, network.ID) 103 104 // Create Subnet 105 subnet, err := CreateSubnetWithDefaultGateway(t, client, network.ID) 106 th.AssertNoErr(t, err) 107 defer DeleteSubnet(t, client, subnet.ID) 108 109 tools.PrintResource(t, subnet) 110 111 if subnet.GatewayIP == "" { 112 t.Fatalf("A default gateway was not created.") 113 } 114 115 var noGateway = "" 116 updateOpts := subnets.UpdateOpts{ 117 GatewayIP: &noGateway, 118 } 119 120 newSubnet, err := subnets.Update(client, subnet.ID, updateOpts).Extract() 121 th.AssertNoErr(t, err) 122 123 if newSubnet.GatewayIP != "" { 124 t.Fatalf("Gateway was not updated correctly") 125 } 126 } 127 128 func TestSubnetsNoGateway(t *testing.T) { 129 client, err := clients.NewNetworkV2Client() 130 th.AssertNoErr(t, err) 131 132 // Create Network 133 network, err := CreateNetwork(t, client) 134 th.AssertNoErr(t, err) 135 defer DeleteNetwork(t, client, network.ID) 136 137 // Create Subnet 138 subnet, err := CreateSubnetWithNoGateway(t, client, network.ID) 139 th.AssertNoErr(t, err) 140 defer DeleteSubnet(t, client, subnet.ID) 141 142 tools.PrintResource(t, subnet) 143 144 if subnet.GatewayIP != "" { 145 t.Fatalf("A gateway exists when it shouldn't.") 146 } 147 148 subnetParts := strings.Split(subnet.CIDR, ".") 149 newGateway := fmt.Sprintf("%s.%s.%s.1", subnetParts[0], subnetParts[1], subnetParts[2]) 150 updateOpts := subnets.UpdateOpts{ 151 GatewayIP: &newGateway, 152 } 153 154 newSubnet, err := subnets.Update(client, subnet.ID, updateOpts).Extract() 155 th.AssertNoErr(t, err) 156 157 if newSubnet.GatewayIP == "" { 158 t.Fatalf("Gateway was not updated correctly") 159 } 160 } 161 162 func TestSubnetsWithSubnetPool(t *testing.T) { 163 client, err := clients.NewNetworkV2Client() 164 th.AssertNoErr(t, err) 165 166 // Create Network 167 network, err := CreateNetwork(t, client) 168 th.AssertNoErr(t, err) 169 defer DeleteNetwork(t, client, network.ID) 170 171 // Create SubnetPool 172 subnetPool, err := subnetpools.CreateSubnetPool(t, client) 173 th.AssertNoErr(t, err) 174 defer subnetpools.DeleteSubnetPool(t, client, subnetPool.ID) 175 176 // Create Subnet 177 subnet, err := CreateSubnetWithSubnetPool(t, client, network.ID, subnetPool.ID) 178 th.AssertNoErr(t, err) 179 defer DeleteSubnet(t, client, subnet.ID) 180 181 tools.PrintResource(t, subnet) 182 183 if subnet.GatewayIP == "" { 184 t.Fatalf("A subnet pool was not associated.") 185 } 186 } 187 188 func TestSubnetsWithSubnetPoolNoCIDR(t *testing.T) { 189 client, err := clients.NewNetworkV2Client() 190 th.AssertNoErr(t, err) 191 192 // Create Network 193 network, err := CreateNetwork(t, client) 194 th.AssertNoErr(t, err) 195 defer DeleteNetwork(t, client, network.ID) 196 197 // Create SubnetPool 198 subnetPool, err := subnetpools.CreateSubnetPool(t, client) 199 th.AssertNoErr(t, err) 200 defer subnetpools.DeleteSubnetPool(t, client, subnetPool.ID) 201 202 // Create Subnet 203 subnet, err := CreateSubnetWithSubnetPoolNoCIDR(t, client, network.ID, subnetPool.ID) 204 th.AssertNoErr(t, err) 205 defer DeleteSubnet(t, client, subnet.ID) 206 207 tools.PrintResource(t, subnet) 208 209 if subnet.GatewayIP == "" { 210 t.Fatalf("A subnet pool was not associated.") 211 } 212 } 213 214 func TestSubnetsWithSubnetPoolPrefixlen(t *testing.T) { 215 client, err := clients.NewNetworkV2Client() 216 th.AssertNoErr(t, err) 217 218 // Create Network 219 network, err := CreateNetwork(t, client) 220 th.AssertNoErr(t, err) 221 defer DeleteNetwork(t, client, network.ID) 222 223 // Create SubnetPool 224 subnetPool, err := subnetpools.CreateSubnetPool(t, client) 225 th.AssertNoErr(t, err) 226 defer subnetpools.DeleteSubnetPool(t, client, subnetPool.ID) 227 228 // Create Subnet 229 subnet, err := CreateSubnetWithSubnetPoolPrefixlen(t, client, network.ID, subnetPool.ID) 230 th.AssertNoErr(t, err) 231 defer DeleteSubnet(t, client, subnet.ID) 232 233 tools.PrintResource(t, subnet) 234 235 if subnet.GatewayIP == "" { 236 t.Fatalf("A subnet pool was not associated.") 237 } 238 239 cidrParts := strings.Split(subnet.CIDR, "/") 240 if len(cidrParts) != 2 { 241 t.Fatalf("Got invalid CIDR for subnet '%s': %s", subnet.ID, subnet.CIDR) 242 } 243 244 if cidrParts[1] != "12" { 245 t.Fatalf("Got invalid prefix length for subnet '%s': wanted 12 but got '%s'", subnet.ID, cidrParts[1]) 246 } 247 } 248 249 func TestSubnetDNSNameservers(t *testing.T) { 250 client, err := clients.NewNetworkV2Client() 251 th.AssertNoErr(t, err) 252 253 // Create Network 254 network, err := CreateNetwork(t, client) 255 th.AssertNoErr(t, err) 256 defer DeleteNetwork(t, client, network.ID) 257 258 // Create Subnet 259 subnet, err := CreateSubnet(t, client, network.ID) 260 th.AssertNoErr(t, err) 261 defer DeleteSubnet(t, client, subnet.ID) 262 263 tools.PrintResource(t, subnet) 264 265 // Update Subnet 266 dnsNameservers := []string{"1.1.1.1"} 267 updateOpts := subnets.UpdateOpts{ 268 DNSNameservers: &dnsNameservers, 269 } 270 _, err = subnets.Update(client, subnet.ID, updateOpts).Extract() 271 th.AssertNoErr(t, err) 272 273 // Get subnet 274 newSubnet, err := subnets.Get(client, subnet.ID).Extract() 275 th.AssertNoErr(t, err) 276 277 tools.PrintResource(t, newSubnet) 278 th.AssertEquals(t, len(newSubnet.DNSNameservers), 1) 279 280 // Update Subnet again 281 dnsNameservers = []string{} 282 updateOpts = subnets.UpdateOpts{ 283 DNSNameservers: &dnsNameservers, 284 } 285 _, err = subnets.Update(client, subnet.ID, updateOpts).Extract() 286 th.AssertNoErr(t, err) 287 288 // Get subnet 289 newSubnet, err = subnets.Get(client, subnet.ID).Extract() 290 th.AssertNoErr(t, err) 291 292 tools.PrintResource(t, newSubnet) 293 th.AssertEquals(t, len(newSubnet.DNSNameservers), 0) 294 } 295 296 func TestSubnetsRevision(t *testing.T) { 297 client, err := clients.NewNetworkV2Client() 298 th.AssertNoErr(t, err) 299 300 // Create Network 301 network, err := CreateNetwork(t, client) 302 th.AssertNoErr(t, err) 303 defer DeleteNetwork(t, client, network.ID) 304 305 // Create Subnet 306 subnet, err := CreateSubnet(t, client, network.ID) 307 th.AssertNoErr(t, err) 308 defer DeleteSubnet(t, client, subnet.ID) 309 310 tools.PrintResource(t, subnet) 311 312 // Store the current revision number. 313 oldRevisionNumber := subnet.RevisionNumber 314 315 // Update Subnet without revision number. 316 // This should work. 317 newSubnetName := tools.RandomString("TESTACC-", 8) 318 newSubnetDescription := "" 319 updateOpts := &subnets.UpdateOpts{ 320 Name: &newSubnetName, 321 Description: &newSubnetDescription, 322 } 323 subnet, err = subnets.Update(client, subnet.ID, updateOpts).Extract() 324 th.AssertNoErr(t, err) 325 326 tools.PrintResource(t, subnet) 327 328 // This should fail due to an old revision number. 329 newSubnetDescription = "new description" 330 updateOpts = &subnets.UpdateOpts{ 331 Name: &newSubnetName, 332 Description: &newSubnetDescription, 333 RevisionNumber: &oldRevisionNumber, 334 } 335 _, err = subnets.Update(client, subnet.ID, updateOpts).Extract() 336 th.AssertErr(t, err) 337 if !strings.Contains(err.Error(), "RevisionNumberConstraintFailed") { 338 t.Fatalf("expected to see an error of type RevisionNumberConstraintFailed, but got the following error instead: %v", err) 339 } 340 341 // Reread the subnet to show that it did not change. 342 subnet, err = subnets.Get(client, subnet.ID).Extract() 343 th.AssertNoErr(t, err) 344 345 tools.PrintResource(t, subnet) 346 347 // This should work because now we do provide a valid revision number. 348 newSubnetDescription = "new description" 349 updateOpts = &subnets.UpdateOpts{ 350 Name: &newSubnetName, 351 Description: &newSubnetDescription, 352 RevisionNumber: &subnet.RevisionNumber, 353 } 354 subnet, err = subnets.Update(client, subnet.ID, updateOpts).Extract() 355 th.AssertNoErr(t, err) 356 357 tools.PrintResource(t, subnet) 358 359 th.AssertEquals(t, subnet.Name, newSubnetName) 360 th.AssertEquals(t, subnet.Description, newSubnetDescription) 361 }