github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/internal/acceptance/openstack/networking/v2/ports_test.go (about) 1 //go:build acceptance || networking || ports 2 3 package v2 4 5 import ( 6 "context" 7 "fmt" 8 "strings" 9 "testing" 10 11 "github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/clients" 12 extensions "github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/openstack/networking/v2/extensions" 13 "github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/tools" 14 "github.com/vnpaycloud-console/gophercloud/v2/openstack/networking/v2/extensions/extradhcpopts" 15 "github.com/vnpaycloud-console/gophercloud/v2/openstack/networking/v2/extensions/portsecurity" 16 "github.com/vnpaycloud-console/gophercloud/v2/openstack/networking/v2/ports" 17 th "github.com/vnpaycloud-console/gophercloud/v2/testhelper" 18 ) 19 20 func TestPortsCRUD(t *testing.T) { 21 client, err := clients.NewNetworkV2Client() 22 th.AssertNoErr(t, err) 23 24 // Create Network 25 network, err := CreateNetwork(t, client) 26 th.AssertNoErr(t, err) 27 defer DeleteNetwork(t, client, network.ID) 28 29 // Create Subnet 30 subnet, err := CreateSubnet(t, client, network.ID) 31 th.AssertNoErr(t, err) 32 defer DeleteSubnet(t, client, subnet.ID) 33 34 // Create port 35 port, err := CreatePort(t, client, network.ID, subnet.ID) 36 th.AssertNoErr(t, err) 37 defer DeletePort(t, client, port.ID) 38 39 if len(port.SecurityGroups) != 1 { 40 t.Logf("WARNING: Port did not have a default security group applied") 41 } 42 43 tools.PrintResource(t, port) 44 45 // Update port 46 newPortName := "" 47 newPortDescription := "" 48 updateOpts := ports.UpdateOpts{ 49 Name: &newPortName, 50 Description: &newPortDescription, 51 } 52 newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 53 th.AssertNoErr(t, err) 54 55 tools.PrintResource(t, newPort) 56 57 th.AssertEquals(t, newPort.Name, newPortName) 58 th.AssertEquals(t, newPort.Description, newPortDescription) 59 60 allPages, err := ports.List(client, nil).AllPages(context.TODO()) 61 th.AssertNoErr(t, err) 62 63 allPorts, err := ports.ExtractPorts(allPages) 64 th.AssertNoErr(t, err) 65 66 var found bool 67 for _, port := range allPorts { 68 if port.ID == newPort.ID { 69 found = true 70 } 71 } 72 73 th.AssertEquals(t, found, true) 74 75 ipAddress := port.FixedIPs[0].IPAddress 76 t.Logf("Port has IP address: %s", ipAddress) 77 78 // List ports by fixed IP 79 // All of the following listOpts should return the port 80 for _, tt := range []struct { 81 name string 82 opts ports.ListOpts 83 expectedPorts int 84 }{ 85 { 86 name: "Port ID", 87 opts: ports.ListOpts{ 88 ID: port.ID, 89 }, 90 expectedPorts: 1, 91 }, 92 { 93 name: "Network ID", 94 opts: ports.ListOpts{ 95 NetworkID: port.NetworkID, 96 }, 97 expectedPorts: 2, // Will also return DHCP port 98 }, 99 { 100 name: "Subnet ID", 101 opts: ports.ListOpts{ 102 FixedIPs: []ports.FixedIPOpts{ 103 {SubnetID: subnet.ID}, 104 }, 105 }, 106 expectedPorts: 1, 107 }, 108 { 109 name: "IP Address", 110 opts: ports.ListOpts{ 111 FixedIPs: []ports.FixedIPOpts{ 112 {IPAddress: ipAddress}, 113 }, 114 }, 115 expectedPorts: 1, 116 }, 117 { 118 name: "Subnet ID and IP Address", 119 opts: ports.ListOpts{ 120 FixedIPs: []ports.FixedIPOpts{ 121 {SubnetID: subnet.ID, IPAddress: ipAddress}, 122 }, 123 }, 124 expectedPorts: 1, 125 }, 126 } { 127 t.Run(fmt.Sprintf("List ports by %s", tt.name), func(t *testing.T) { 128 allPages, err := ports.List(client, tt.opts).AllPages(context.TODO()) 129 th.AssertNoErr(t, err) 130 131 allPorts, err := ports.ExtractPorts(allPages) 132 th.AssertNoErr(t, err) 133 134 logPorts := func() { 135 for _, port := range allPorts { 136 tools.PrintResource(t, port) 137 } 138 } 139 140 if len(allPorts) != tt.expectedPorts { 141 if len(allPorts) == 0 { 142 t.Fatalf("Port not found") 143 } 144 if len(allPorts) > 1 { 145 logPorts() 146 t.Fatalf("Expected %d port but got %d", tt.expectedPorts, len(allPorts)) 147 } 148 } 149 func() { 150 for _, port := range allPorts { 151 if port.ID == newPort.ID { 152 return 153 } 154 } 155 logPorts() 156 t.Fatalf("Returned ports did not contain expected port") 157 }() 158 }) 159 } 160 } 161 162 func TestPortsRemoveSecurityGroups(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 Subnet 172 subnet, err := CreateSubnet(t, client, network.ID) 173 th.AssertNoErr(t, err) 174 defer DeleteSubnet(t, client, subnet.ID) 175 176 // Create port 177 port, err := CreatePort(t, client, network.ID, subnet.ID) 178 th.AssertNoErr(t, err) 179 defer DeletePort(t, client, port.ID) 180 181 tools.PrintResource(t, port) 182 183 // Create a Security Group 184 group, err := extensions.CreateSecurityGroup(t, client) 185 th.AssertNoErr(t, err) 186 defer extensions.DeleteSecurityGroup(t, client, group.ID) 187 188 // Add the group to the port 189 updateOpts := ports.UpdateOpts{ 190 SecurityGroups: &[]string{group.ID}, 191 } 192 _, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 193 th.AssertNoErr(t, err) 194 195 // Remove the group 196 updateOpts = ports.UpdateOpts{ 197 SecurityGroups: &[]string{}, 198 } 199 newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 200 th.AssertNoErr(t, err) 201 202 tools.PrintResource(t, newPort) 203 204 if len(newPort.SecurityGroups) > 0 { 205 t.Fatalf("Unable to remove security group from port") 206 } 207 } 208 209 func TestPortsDontAlterSecurityGroups(t *testing.T) { 210 client, err := clients.NewNetworkV2Client() 211 th.AssertNoErr(t, err) 212 213 // Create Network 214 network, err := CreateNetwork(t, client) 215 th.AssertNoErr(t, err) 216 defer DeleteNetwork(t, client, network.ID) 217 218 // Create Subnet 219 subnet, err := CreateSubnet(t, client, network.ID) 220 th.AssertNoErr(t, err) 221 defer DeleteSubnet(t, client, subnet.ID) 222 223 // Create a Security Group 224 group, err := extensions.CreateSecurityGroup(t, client) 225 th.AssertNoErr(t, err) 226 defer extensions.DeleteSecurityGroup(t, client, group.ID) 227 228 // Create port 229 port, err := CreatePort(t, client, network.ID, subnet.ID) 230 th.AssertNoErr(t, err) 231 defer DeletePort(t, client, port.ID) 232 233 tools.PrintResource(t, port) 234 235 // Add the group to the port 236 updateOpts := ports.UpdateOpts{ 237 SecurityGroups: &[]string{group.ID}, 238 } 239 _, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 240 th.AssertNoErr(t, err) 241 242 // Update the port again 243 var name = "some_port" 244 updateOpts = ports.UpdateOpts{ 245 Name: &name, 246 } 247 newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 248 th.AssertNoErr(t, err) 249 250 tools.PrintResource(t, newPort) 251 252 if len(newPort.SecurityGroups) == 0 { 253 t.Fatalf("Port had security group updated") 254 } 255 } 256 257 func TestPortsWithNoSecurityGroup(t *testing.T) { 258 client, err := clients.NewNetworkV2Client() 259 th.AssertNoErr(t, err) 260 261 // Create Network 262 network, err := CreateNetwork(t, client) 263 th.AssertNoErr(t, err) 264 defer DeleteNetwork(t, client, network.ID) 265 266 // Create Subnet 267 subnet, err := CreateSubnet(t, client, network.ID) 268 th.AssertNoErr(t, err) 269 defer DeleteSubnet(t, client, subnet.ID) 270 271 // Create port 272 port, err := CreatePortWithNoSecurityGroup(t, client, network.ID, subnet.ID) 273 th.AssertNoErr(t, err) 274 defer DeletePort(t, client, port.ID) 275 276 tools.PrintResource(t, port) 277 278 if len(port.SecurityGroups) != 0 { 279 t.Fatalf("Port was created with security groups") 280 } 281 } 282 283 func TestPortsRemoveAddressPair(t *testing.T) { 284 client, err := clients.NewNetworkV2Client() 285 th.AssertNoErr(t, err) 286 287 // Create Network 288 network, err := CreateNetwork(t, client) 289 th.AssertNoErr(t, err) 290 defer DeleteNetwork(t, client, network.ID) 291 292 // Create Subnet 293 subnet, err := CreateSubnet(t, client, network.ID) 294 th.AssertNoErr(t, err) 295 defer DeleteSubnet(t, client, subnet.ID) 296 297 // Create port 298 port, err := CreatePort(t, client, network.ID, subnet.ID) 299 th.AssertNoErr(t, err) 300 defer DeletePort(t, client, port.ID) 301 302 tools.PrintResource(t, port) 303 304 // Add an address pair to the port 305 updateOpts := ports.UpdateOpts{ 306 AllowedAddressPairs: &[]ports.AddressPair{ 307 {IPAddress: "192.168.255.10", MACAddress: "aa:bb:cc:dd:ee:ff"}, 308 }, 309 } 310 _, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 311 th.AssertNoErr(t, err) 312 313 // Remove the address pair 314 updateOpts = ports.UpdateOpts{ 315 AllowedAddressPairs: &[]ports.AddressPair{}, 316 } 317 newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 318 th.AssertNoErr(t, err) 319 320 tools.PrintResource(t, newPort) 321 322 if len(newPort.AllowedAddressPairs) > 0 { 323 t.Fatalf("Unable to remove the address pair") 324 } 325 } 326 327 func TestPortsDontUpdateAllowedAddressPairs(t *testing.T) { 328 client, err := clients.NewNetworkV2Client() 329 th.AssertNoErr(t, err) 330 331 // Create Network 332 network, err := CreateNetwork(t, client) 333 th.AssertNoErr(t, err) 334 defer DeleteNetwork(t, client, network.ID) 335 336 // Create Subnet 337 subnet, err := CreateSubnet(t, client, network.ID) 338 th.AssertNoErr(t, err) 339 defer DeleteSubnet(t, client, subnet.ID) 340 341 // Create port 342 port, err := CreatePort(t, client, network.ID, subnet.ID) 343 th.AssertNoErr(t, err) 344 defer DeletePort(t, client, port.ID) 345 346 tools.PrintResource(t, port) 347 348 // Add an address pair to the port 349 updateOpts := ports.UpdateOpts{ 350 AllowedAddressPairs: &[]ports.AddressPair{ 351 {IPAddress: "192.168.255.10", MACAddress: "aa:bb:cc:dd:ee:ff"}, 352 }, 353 } 354 newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 355 th.AssertNoErr(t, err) 356 357 tools.PrintResource(t, newPort) 358 359 // Remove the address pair 360 var name = "some_port" 361 updateOpts = ports.UpdateOpts{ 362 Name: &name, 363 } 364 newPort, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 365 th.AssertNoErr(t, err) 366 367 tools.PrintResource(t, newPort) 368 369 if len(newPort.AllowedAddressPairs) == 0 { 370 t.Fatalf("Address Pairs were removed") 371 } 372 } 373 374 func TestPortsPortSecurityCRUD(t *testing.T) { 375 client, err := clients.NewNetworkV2Client() 376 th.AssertNoErr(t, err) 377 378 // Create Network 379 network, err := CreateNetwork(t, client) 380 th.AssertNoErr(t, err) 381 defer DeleteNetwork(t, client, network.ID) 382 383 // Create Subnet 384 subnet, err := CreateSubnet(t, client, network.ID) 385 th.AssertNoErr(t, err) 386 defer DeleteSubnet(t, client, subnet.ID) 387 388 // Create port 389 port, err := CreatePortWithoutPortSecurity(t, client, network.ID, subnet.ID) 390 th.AssertNoErr(t, err) 391 defer DeletePort(t, client, port.ID) 392 393 var portWithExt struct { 394 ports.Port 395 portsecurity.PortSecurityExt 396 } 397 398 err = ports.Get(context.TODO(), client, port.ID).ExtractInto(&portWithExt) 399 th.AssertNoErr(t, err) 400 401 tools.PrintResource(t, portWithExt) 402 403 iTrue := true 404 portUpdateOpts := ports.UpdateOpts{} 405 updateOpts := portsecurity.PortUpdateOptsExt{ 406 UpdateOptsBuilder: portUpdateOpts, 407 PortSecurityEnabled: &iTrue, 408 } 409 410 err = ports.Update(context.TODO(), client, port.ID, updateOpts).ExtractInto(&portWithExt) 411 th.AssertNoErr(t, err) 412 413 tools.PrintResource(t, portWithExt) 414 } 415 416 func TestPortsWithExtraDHCPOptsCRUD(t *testing.T) { 417 client, err := clients.NewNetworkV2Client() 418 th.AssertNoErr(t, err) 419 420 // Create a Network 421 network, err := CreateNetwork(t, client) 422 th.AssertNoErr(t, err) 423 defer DeleteNetwork(t, client, network.ID) 424 425 // Create a Subnet 426 subnet, err := CreateSubnet(t, client, network.ID) 427 th.AssertNoErr(t, err) 428 defer DeleteSubnet(t, client, subnet.ID) 429 430 // Create a port with extra DHCP options. 431 port, err := CreatePortWithExtraDHCPOpts(t, client, network.ID, subnet.ID) 432 th.AssertNoErr(t, err) 433 defer DeletePort(t, client, port.ID) 434 435 tools.PrintResource(t, port) 436 437 // Update the port with extra DHCP options. 438 newPortName := tools.RandomString("TESTACC-", 8) 439 portUpdateOpts := ports.UpdateOpts{ 440 Name: &newPortName, 441 } 442 443 existingOpt := port.ExtraDHCPOpts[0] 444 newOptValue := "test_value_2" 445 446 updateOpts := extradhcpopts.UpdateOptsExt{ 447 UpdateOptsBuilder: portUpdateOpts, 448 ExtraDHCPOpts: []extradhcpopts.UpdateExtraDHCPOpt{ 449 { 450 OptName: existingOpt.OptName, 451 OptValue: nil, 452 }, 453 { 454 OptName: "test_option_2", 455 OptValue: &newOptValue, 456 }, 457 }, 458 } 459 460 newPort := &PortWithExtraDHCPOpts{} 461 err = ports.Update(context.TODO(), client, port.ID, updateOpts).ExtractInto(newPort) 462 th.AssertNoErr(t, err) 463 464 tools.PrintResource(t, newPort) 465 } 466 467 func TestPortsRevision(t *testing.T) { 468 client, err := clients.NewNetworkV2Client() 469 th.AssertNoErr(t, err) 470 471 // Create Network 472 network, err := CreateNetwork(t, client) 473 th.AssertNoErr(t, err) 474 defer DeleteNetwork(t, client, network.ID) 475 476 // Create Subnet 477 subnet, err := CreateSubnet(t, client, network.ID) 478 th.AssertNoErr(t, err) 479 defer DeleteSubnet(t, client, subnet.ID) 480 481 // Create port 482 port, err := CreatePort(t, client, network.ID, subnet.ID) 483 th.AssertNoErr(t, err) 484 defer DeletePort(t, client, port.ID) 485 486 tools.PrintResource(t, port) 487 488 // Add an address pair to the port 489 // Use the RevisionNumber to test the revision / If-Match logic. 490 updateOpts := ports.UpdateOpts{ 491 AllowedAddressPairs: &[]ports.AddressPair{ 492 {IPAddress: "192.168.255.10", MACAddress: "aa:bb:cc:dd:ee:ff"}, 493 }, 494 RevisionNumber: &port.RevisionNumber, 495 } 496 newPort, err := ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 497 th.AssertNoErr(t, err) 498 499 tools.PrintResource(t, newPort) 500 501 // Remove the address pair - this should fail due to old revision number. 502 updateOpts = ports.UpdateOpts{ 503 AllowedAddressPairs: &[]ports.AddressPair{}, 504 RevisionNumber: &port.RevisionNumber, 505 } 506 _, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 507 th.AssertErr(t, err) 508 if !strings.Contains(err.Error(), "RevisionNumberConstraintFailed") { 509 t.Fatalf("expected to see an error of type RevisionNumberConstraintFailed, but got the following error instead: %v", err) 510 } 511 512 // The previous ports.Update returns an empty object, so get the port again. 513 newPort, err = ports.Get(context.TODO(), client, port.ID).Extract() 514 th.AssertNoErr(t, err) 515 tools.PrintResource(t, newPort) 516 517 // When not specifying a RevisionNumber, then the If-Match mechanism 518 // should be bypassed. 519 updateOpts = ports.UpdateOpts{ 520 AllowedAddressPairs: &[]ports.AddressPair{}, 521 } 522 newPort, err = ports.Update(context.TODO(), client, port.ID, updateOpts).Extract() 523 th.AssertNoErr(t, err) 524 525 tools.PrintResource(t, newPort) 526 527 if len(newPort.AllowedAddressPairs) > 0 { 528 t.Fatalf("Unable to remove the address pair") 529 } 530 }