github.com/gophercloud/gophercloud@v1.11.0/internal/acceptance/openstack/networking/v2/networking.go (about) 1 package v2 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/gophercloud/gophercloud" 8 "github.com/gophercloud/gophercloud/internal/acceptance/tools" 9 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/extradhcpopts" 10 "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/portsecurity" 11 "github.com/gophercloud/gophercloud/openstack/networking/v2/networks" 12 "github.com/gophercloud/gophercloud/openstack/networking/v2/ports" 13 "github.com/gophercloud/gophercloud/openstack/networking/v2/subnets" 14 th "github.com/gophercloud/gophercloud/testhelper" 15 ) 16 17 // PortWithExtraDHCPOpts represents a port with extra DHCP options configuration. 18 type PortWithExtraDHCPOpts struct { 19 ports.Port 20 extradhcpopts.ExtraDHCPOptsExt 21 } 22 23 // CreateNetwork will create basic network. An error will be returned if the 24 // network could not be created. 25 func CreateNetwork(t *testing.T, client *gophercloud.ServiceClient) (*networks.Network, error) { 26 networkName := tools.RandomString("TESTACC-", 8) 27 networkDescription := tools.RandomString("TESTACC-DESC-", 8) 28 createOpts := networks.CreateOpts{ 29 Name: networkName, 30 Description: networkDescription, 31 AdminStateUp: gophercloud.Enabled, 32 } 33 34 t.Logf("Attempting to create network: %s", networkName) 35 36 network, err := networks.Create(client, createOpts).Extract() 37 if err != nil { 38 return network, err 39 } 40 41 t.Logf("Successfully created network.") 42 43 th.AssertEquals(t, network.Name, networkName) 44 th.AssertEquals(t, network.Description, networkDescription) 45 46 return network, nil 47 } 48 49 // CreateNetworkWithoutPortSecurity will create a network without port security. 50 // An error will be returned if the network could not be created. 51 func CreateNetworkWithoutPortSecurity(t *testing.T, client *gophercloud.ServiceClient) (*networks.Network, error) { 52 networkName := tools.RandomString("TESTACC-", 8) 53 networkCreateOpts := networks.CreateOpts{ 54 Name: networkName, 55 AdminStateUp: gophercloud.Enabled, 56 } 57 58 iFalse := false 59 createOpts := portsecurity.NetworkCreateOptsExt{ 60 CreateOptsBuilder: networkCreateOpts, 61 PortSecurityEnabled: &iFalse, 62 } 63 64 t.Logf("Attempting to create network: %s", networkName) 65 66 network, err := networks.Create(client, createOpts).Extract() 67 if err != nil { 68 return network, err 69 } 70 71 t.Logf("Successfully created network.") 72 73 th.AssertEquals(t, network.Name, networkName) 74 75 return network, nil 76 } 77 78 // CreatePort will create a port on the specified subnet. An error will be 79 // returned if the port could not be created. 80 func CreatePort(t *testing.T, client *gophercloud.ServiceClient, networkID, subnetID string) (*ports.Port, error) { 81 portName := tools.RandomString("TESTACC-", 8) 82 portDescription := tools.RandomString("TESTACC-DESC-", 8) 83 84 t.Logf("Attempting to create port: %s", portName) 85 86 createOpts := ports.CreateOpts{ 87 NetworkID: networkID, 88 Name: portName, 89 Description: portDescription, 90 AdminStateUp: gophercloud.Enabled, 91 FixedIPs: []ports.IP{{SubnetID: subnetID}}, 92 } 93 94 port, err := ports.Create(client, createOpts).Extract() 95 if err != nil { 96 return port, err 97 } 98 99 if err := WaitForPortToCreate(client, port.ID); err != nil { 100 return port, err 101 } 102 103 newPort, err := ports.Get(client, port.ID).Extract() 104 if err != nil { 105 return newPort, err 106 } 107 108 t.Logf("Successfully created port: %s", portName) 109 110 th.AssertEquals(t, port.Name, portName) 111 th.AssertEquals(t, port.Description, portDescription) 112 113 return newPort, nil 114 } 115 116 // CreatePortWithNoSecurityGroup will create a port with no security group 117 // attached. An error will be returned if the port could not be created. 118 func CreatePortWithNoSecurityGroup(t *testing.T, client *gophercloud.ServiceClient, networkID, subnetID string) (*ports.Port, error) { 119 portName := tools.RandomString("TESTACC-", 8) 120 iFalse := false 121 122 t.Logf("Attempting to create port: %s", portName) 123 124 createOpts := ports.CreateOpts{ 125 NetworkID: networkID, 126 Name: portName, 127 AdminStateUp: &iFalse, 128 FixedIPs: []ports.IP{{SubnetID: subnetID}}, 129 SecurityGroups: &[]string{}, 130 } 131 132 port, err := ports.Create(client, createOpts).Extract() 133 if err != nil { 134 return port, err 135 } 136 137 if err := WaitForPortToCreate(client, port.ID); err != nil { 138 return port, err 139 } 140 141 newPort, err := ports.Get(client, port.ID).Extract() 142 if err != nil { 143 return newPort, err 144 } 145 146 t.Logf("Successfully created port: %s", portName) 147 148 th.AssertEquals(t, port.Name, portName) 149 150 return newPort, nil 151 } 152 153 // CreatePortWithoutPortSecurity will create a port without port security on the 154 // specified subnet. An error will be returned if the port could not be created. 155 func CreatePortWithoutPortSecurity(t *testing.T, client *gophercloud.ServiceClient, networkID, subnetID string) (*ports.Port, error) { 156 portName := tools.RandomString("TESTACC-", 8) 157 158 t.Logf("Attempting to create port: %s", portName) 159 160 portCreateOpts := ports.CreateOpts{ 161 NetworkID: networkID, 162 Name: portName, 163 AdminStateUp: gophercloud.Enabled, 164 FixedIPs: []ports.IP{{SubnetID: subnetID}}, 165 } 166 167 iFalse := false 168 createOpts := portsecurity.PortCreateOptsExt{ 169 CreateOptsBuilder: portCreateOpts, 170 PortSecurityEnabled: &iFalse, 171 } 172 173 port, err := ports.Create(client, createOpts).Extract() 174 if err != nil { 175 return port, err 176 } 177 178 if err := WaitForPortToCreate(client, port.ID); err != nil { 179 return port, err 180 } 181 182 newPort, err := ports.Get(client, port.ID).Extract() 183 if err != nil { 184 return newPort, err 185 } 186 187 t.Logf("Successfully created port: %s", portName) 188 189 th.AssertEquals(t, port.Name, portName) 190 191 return newPort, nil 192 } 193 194 // CreatePortWithExtraDHCPOpts will create a port with DHCP options on the 195 // specified subnet. An error will be returned if the port could not be created. 196 func CreatePortWithExtraDHCPOpts(t *testing.T, client *gophercloud.ServiceClient, networkID, subnetID string) (*PortWithExtraDHCPOpts, error) { 197 portName := tools.RandomString("TESTACC-", 8) 198 199 t.Logf("Attempting to create port: %s", portName) 200 201 portCreateOpts := ports.CreateOpts{ 202 NetworkID: networkID, 203 Name: portName, 204 AdminStateUp: gophercloud.Enabled, 205 FixedIPs: []ports.IP{{SubnetID: subnetID}}, 206 } 207 208 createOpts := extradhcpopts.CreateOptsExt{ 209 CreateOptsBuilder: portCreateOpts, 210 ExtraDHCPOpts: []extradhcpopts.CreateExtraDHCPOpt{ 211 { 212 OptName: "test_option_1", 213 OptValue: "test_value_1", 214 }, 215 }, 216 } 217 port := &PortWithExtraDHCPOpts{} 218 219 err := ports.Create(client, createOpts).ExtractInto(port) 220 if err != nil { 221 return nil, err 222 } 223 224 if err := WaitForPortToCreate(client, port.ID); err != nil { 225 return nil, err 226 } 227 228 err = ports.Get(client, port.ID).ExtractInto(port) 229 if err != nil { 230 return port, err 231 } 232 233 t.Logf("Successfully created port: %s", portName) 234 235 return port, nil 236 } 237 238 // CreatePortWithMultipleFixedIPs will create a port with two FixedIPs on the 239 // specified subnet. An error will be returned if the port could not be created. 240 func CreatePortWithMultipleFixedIPs(t *testing.T, client *gophercloud.ServiceClient, networkID, subnetID string) (*ports.Port, error) { 241 portName := tools.RandomString("TESTACC-", 8) 242 portDescription := tools.RandomString("TESTACC-DESC-", 8) 243 244 t.Logf("Attempting to create port with two fixed IPs: %s", portName) 245 246 createOpts := ports.CreateOpts{ 247 NetworkID: networkID, 248 Name: portName, 249 Description: portDescription, 250 AdminStateUp: gophercloud.Enabled, 251 FixedIPs: []ports.IP{{SubnetID: subnetID}, {SubnetID: subnetID}}, 252 } 253 254 port, err := ports.Create(client, createOpts).Extract() 255 if err != nil { 256 return port, err 257 } 258 259 if err := WaitForPortToCreate(client, port.ID); err != nil { 260 return port, err 261 } 262 263 newPort, err := ports.Get(client, port.ID).Extract() 264 if err != nil { 265 return newPort, err 266 } 267 268 t.Logf("Successfully created port: %s", portName) 269 270 th.AssertEquals(t, port.Name, portName) 271 th.AssertEquals(t, port.Description, portDescription) 272 273 if len(port.FixedIPs) != 2 { 274 t.Fatalf("Failed to create a port with two fixed IPs: %s", portName) 275 } 276 277 return newPort, nil 278 } 279 280 // CreateSubnet will create a subnet on the specified Network ID. An error 281 // will be returned if the subnet could not be created. 282 func CreateSubnet(t *testing.T, client *gophercloud.ServiceClient, networkID string) (*subnets.Subnet, error) { 283 subnetName := tools.RandomString("TESTACC-", 8) 284 subnetDescription := tools.RandomString("TESTACC-DESC-", 8) 285 subnetOctet := tools.RandomInt(1, 250) 286 subnetCIDR := fmt.Sprintf("192.168.%d.0/24", subnetOctet) 287 subnetGateway := fmt.Sprintf("192.168.%d.1", subnetOctet) 288 createOpts := subnets.CreateOpts{ 289 NetworkID: networkID, 290 CIDR: subnetCIDR, 291 IPVersion: 4, 292 Name: subnetName, 293 Description: subnetDescription, 294 EnableDHCP: gophercloud.Disabled, 295 GatewayIP: &subnetGateway, 296 } 297 298 t.Logf("Attempting to create subnet: %s", subnetName) 299 300 subnet, err := subnets.Create(client, createOpts).Extract() 301 if err != nil { 302 return subnet, err 303 } 304 305 t.Logf("Successfully created subnet.") 306 307 th.AssertEquals(t, subnet.Name, subnetName) 308 th.AssertEquals(t, subnet.Description, subnetDescription) 309 th.AssertEquals(t, subnet.GatewayIP, subnetGateway) 310 th.AssertEquals(t, subnet.CIDR, subnetCIDR) 311 312 return subnet, nil 313 } 314 315 // CreateSubnet will create a subnet on the specified Network ID and service types. 316 // 317 // An error will be returned if the subnet could not be created. 318 func CreateSubnetWithServiceTypes(t *testing.T, client *gophercloud.ServiceClient, networkID string) (*subnets.Subnet, error) { 319 subnetName := tools.RandomString("TESTACC-", 8) 320 subnetDescription := tools.RandomString("TESTACC-DESC-", 8) 321 subnetOctet := tools.RandomInt(1, 250) 322 subnetCIDR := fmt.Sprintf("192.168.%d.0/24", subnetOctet) 323 subnetGateway := fmt.Sprintf("192.168.%d.1", subnetOctet) 324 serviceTypes := []string{"network:routed"} 325 createOpts := subnets.CreateOpts{ 326 NetworkID: networkID, 327 CIDR: subnetCIDR, 328 IPVersion: 4, 329 Name: subnetName, 330 Description: subnetDescription, 331 EnableDHCP: gophercloud.Disabled, 332 GatewayIP: &subnetGateway, 333 ServiceTypes: serviceTypes, 334 } 335 336 t.Logf("Attempting to create subnet: %s", subnetName) 337 338 subnet, err := subnets.Create(client, createOpts).Extract() 339 if err != nil { 340 return subnet, err 341 } 342 343 t.Logf("Successfully created subnet.") 344 345 th.AssertEquals(t, subnet.Name, subnetName) 346 th.AssertEquals(t, subnet.Description, subnetDescription) 347 th.AssertEquals(t, subnet.GatewayIP, subnetGateway) 348 th.AssertEquals(t, subnet.CIDR, subnetCIDR) 349 th.AssertDeepEquals(t, subnet.ServiceTypes, serviceTypes) 350 351 return subnet, nil 352 } 353 354 // CreateSubnetWithDefaultGateway will create a subnet on the specified Network 355 // ID and have Neutron set the gateway by default An error will be returned if 356 // the subnet could not be created. 357 func CreateSubnetWithDefaultGateway(t *testing.T, client *gophercloud.ServiceClient, networkID string) (*subnets.Subnet, error) { 358 subnetName := tools.RandomString("TESTACC-", 8) 359 subnetOctet := tools.RandomInt(1, 250) 360 subnetCIDR := fmt.Sprintf("192.168.%d.0/24", subnetOctet) 361 defaultGateway := fmt.Sprintf("192.168.%d.1", subnetOctet) 362 363 createOpts := subnets.CreateOpts{ 364 NetworkID: networkID, 365 CIDR: subnetCIDR, 366 IPVersion: 4, 367 Name: subnetName, 368 EnableDHCP: gophercloud.Disabled, 369 } 370 371 t.Logf("Attempting to create subnet: %s", subnetName) 372 373 subnet, err := subnets.Create(client, createOpts).Extract() 374 if err != nil { 375 return subnet, err 376 } 377 378 t.Logf("Successfully created subnet.") 379 380 th.AssertEquals(t, subnet.Name, subnetName) 381 th.AssertEquals(t, subnet.GatewayIP, defaultGateway) 382 th.AssertEquals(t, subnet.CIDR, subnetCIDR) 383 384 return subnet, nil 385 } 386 387 // CreateSubnetWithNoGateway will create a subnet with no gateway on the 388 // specified Network ID. An error will be returned if the subnet could not be 389 // created. 390 func CreateSubnetWithNoGateway(t *testing.T, client *gophercloud.ServiceClient, networkID string) (*subnets.Subnet, error) { 391 var noGateway = "" 392 subnetName := tools.RandomString("TESTACC-", 8) 393 subnetOctet := tools.RandomInt(1, 250) 394 subnetCIDR := fmt.Sprintf("192.168.%d.0/24", subnetOctet) 395 dhcpStart := fmt.Sprintf("192.168.%d.10", subnetOctet) 396 dhcpEnd := fmt.Sprintf("192.168.%d.200", subnetOctet) 397 createOpts := subnets.CreateOpts{ 398 NetworkID: networkID, 399 CIDR: subnetCIDR, 400 IPVersion: 4, 401 Name: subnetName, 402 EnableDHCP: gophercloud.Disabled, 403 GatewayIP: &noGateway, 404 AllocationPools: []subnets.AllocationPool{ 405 { 406 Start: dhcpStart, 407 End: dhcpEnd, 408 }, 409 }, 410 } 411 412 t.Logf("Attempting to create subnet: %s", subnetName) 413 414 subnet, err := subnets.Create(client, createOpts).Extract() 415 if err != nil { 416 return subnet, err 417 } 418 419 t.Logf("Successfully created subnet.") 420 421 th.AssertEquals(t, subnet.Name, subnetName) 422 th.AssertEquals(t, subnet.GatewayIP, "") 423 th.AssertEquals(t, subnet.CIDR, subnetCIDR) 424 425 return subnet, nil 426 } 427 428 // CreateSubnetWithSubnetPool will create a subnet associated with the provided subnetpool on the specified Network ID. 429 // An error will be returned if the subnet or the subnetpool could not be created. 430 func CreateSubnetWithSubnetPool(t *testing.T, client *gophercloud.ServiceClient, networkID string, subnetPoolID string) (*subnets.Subnet, error) { 431 subnetName := tools.RandomString("TESTACC-", 8) 432 subnetOctet := tools.RandomInt(1, 250) 433 subnetCIDR := fmt.Sprintf("10.%d.0.0/24", subnetOctet) 434 createOpts := subnets.CreateOpts{ 435 NetworkID: networkID, 436 CIDR: subnetCIDR, 437 IPVersion: 4, 438 Name: subnetName, 439 EnableDHCP: gophercloud.Disabled, 440 SubnetPoolID: subnetPoolID, 441 } 442 443 t.Logf("Attempting to create subnet: %s", subnetName) 444 445 subnet, err := subnets.Create(client, createOpts).Extract() 446 if err != nil { 447 return subnet, err 448 } 449 450 t.Logf("Successfully created subnet.") 451 452 th.AssertEquals(t, subnet.Name, subnetName) 453 th.AssertEquals(t, subnet.CIDR, subnetCIDR) 454 455 return subnet, nil 456 } 457 458 // CreateSubnetWithSubnetPoolNoCIDR will create a subnet associated with the 459 // provided subnetpool on the specified Network ID. 460 // An error will be returned if the subnet or the subnetpool could not be created. 461 func CreateSubnetWithSubnetPoolNoCIDR(t *testing.T, client *gophercloud.ServiceClient, networkID string, subnetPoolID string) (*subnets.Subnet, error) { 462 subnetName := tools.RandomString("TESTACC-", 8) 463 createOpts := subnets.CreateOpts{ 464 NetworkID: networkID, 465 IPVersion: 4, 466 Name: subnetName, 467 EnableDHCP: gophercloud.Disabled, 468 SubnetPoolID: subnetPoolID, 469 } 470 471 t.Logf("Attempting to create subnet: %s", subnetName) 472 473 subnet, err := subnets.Create(client, createOpts).Extract() 474 if err != nil { 475 return subnet, err 476 } 477 478 t.Logf("Successfully created subnet.") 479 480 th.AssertEquals(t, subnet.Name, subnetName) 481 482 return subnet, nil 483 } 484 485 // CreateSubnetWithSubnetPoolPrefixlen will create a subnet associated with the 486 // provided subnetpool on the specified Network ID and with overwritten 487 // prefixlen instead of the default subnetpool prefixlen. 488 // An error will be returned if the subnet or the subnetpool could not be created. 489 func CreateSubnetWithSubnetPoolPrefixlen(t *testing.T, client *gophercloud.ServiceClient, networkID string, subnetPoolID string) (*subnets.Subnet, error) { 490 subnetName := tools.RandomString("TESTACC-", 8) 491 createOpts := subnets.CreateOpts{ 492 NetworkID: networkID, 493 IPVersion: 4, 494 Name: subnetName, 495 EnableDHCP: gophercloud.Disabled, 496 SubnetPoolID: subnetPoolID, 497 Prefixlen: 12, 498 } 499 500 t.Logf("Attempting to create subnet: %s", subnetName) 501 502 subnet, err := subnets.Create(client, createOpts).Extract() 503 if err != nil { 504 return subnet, err 505 } 506 507 t.Logf("Successfully created subnet.") 508 509 th.AssertEquals(t, subnet.Name, subnetName) 510 511 return subnet, nil 512 } 513 514 // DeleteNetwork will delete a network with a specified ID. A fatal error will 515 // occur if the delete was not successful. This works best when used as a 516 // deferred function. 517 func DeleteNetwork(t *testing.T, client *gophercloud.ServiceClient, networkID string) { 518 t.Logf("Attempting to delete network: %s", networkID) 519 520 err := networks.Delete(client, networkID).ExtractErr() 521 if err != nil { 522 t.Fatalf("Unable to delete network %s: %v", networkID, err) 523 } 524 525 t.Logf("Deleted network: %s", networkID) 526 } 527 528 // DeletePort will delete a port with a specified ID. A fatal error will 529 // occur if the delete was not successful. This works best when used as a 530 // deferred function. 531 func DeletePort(t *testing.T, client *gophercloud.ServiceClient, portID string) { 532 t.Logf("Attempting to delete port: %s", portID) 533 534 err := ports.Delete(client, portID).ExtractErr() 535 if err != nil { 536 t.Fatalf("Unable to delete port %s: %v", portID, err) 537 } 538 539 t.Logf("Deleted port: %s", portID) 540 } 541 542 // DeleteSubnet will delete a subnet with a specified ID. A fatal error will 543 // occur if the delete was not successful. This works best when used as a 544 // deferred function. 545 func DeleteSubnet(t *testing.T, client *gophercloud.ServiceClient, subnetID string) { 546 t.Logf("Attempting to delete subnet: %s", subnetID) 547 548 err := subnets.Delete(client, subnetID).ExtractErr() 549 if err != nil { 550 t.Fatalf("Unable to delete subnet %s: %v", subnetID, err) 551 } 552 553 t.Logf("Deleted subnet: %s", subnetID) 554 } 555 556 func WaitForPortToCreate(client *gophercloud.ServiceClient, portID string) error { 557 return tools.WaitFor(func() (bool, error) { 558 p, err := ports.Get(client, portID).Extract() 559 if err != nil { 560 return false, err 561 } 562 563 if p.Status == "ACTIVE" || p.Status == "DOWN" { 564 return true, nil 565 } 566 567 return false, nil 568 }) 569 } 570 571 // This is duplicated from https://github.com/gophercloud/utils 572 // so that Gophercloud "core" doesn't have a dependency on the 573 // complementary utils repository. 574 func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) { 575 count := 0 576 id := "" 577 578 listOpts := networks.ListOpts{ 579 Name: name, 580 } 581 582 pages, err := networks.List(client, listOpts).AllPages() 583 if err != nil { 584 return "", err 585 } 586 587 all, err := networks.ExtractNetworks(pages) 588 if err != nil { 589 return "", err 590 } 591 592 for _, s := range all { 593 if s.Name == name { 594 count++ 595 id = s.ID 596 } 597 } 598 599 switch count { 600 case 0: 601 return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "network"} 602 case 1: 603 return id, nil 604 default: 605 return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "network"} 606 } 607 }