github.com/gophercloud/gophercloud@v1.11.0/internal/acceptance/openstack/compute/v2/servers_test.go (about) 1 //go:build acceptance || compute || servers 2 // +build acceptance compute servers 3 4 package v2 5 6 import ( 7 "strings" 8 "testing" 9 10 "github.com/gophercloud/gophercloud" 11 "github.com/gophercloud/gophercloud/internal/acceptance/clients" 12 networks "github.com/gophercloud/gophercloud/internal/acceptance/openstack/networking/v2" 13 "github.com/gophercloud/gophercloud/internal/acceptance/tools" 14 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/attachinterfaces" 15 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones" 16 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/extendedserverattributes" 17 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/extendedstatus" 18 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/lockunlock" 19 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/pauseunpause" 20 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/serverusage" 21 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/suspendresume" 22 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/tags" 23 "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" 24 th "github.com/gophercloud/gophercloud/testhelper" 25 ) 26 27 func TestServersCreateDestroy(t *testing.T) { 28 clients.RequireLong(t) 29 30 client, err := clients.NewComputeV2Client() 31 th.AssertNoErr(t, err) 32 33 choices, err := clients.AcceptanceTestChoicesFromEnv() 34 th.AssertNoErr(t, err) 35 36 server, err := CreateServer(t, client) 37 th.AssertNoErr(t, err) 38 defer DeleteServer(t, client, server) 39 40 allPages, err := servers.List(client, servers.ListOpts{}).AllPages() 41 th.AssertNoErr(t, err) 42 43 allServers, err := servers.ExtractServers(allPages) 44 th.AssertNoErr(t, err) 45 46 var found bool 47 for _, s := range allServers { 48 tools.PrintResource(t, server) 49 50 if s.ID == server.ID { 51 found = true 52 } 53 } 54 55 th.AssertEquals(t, found, true) 56 57 allAddressPages, err := servers.ListAddresses(client, server.ID).AllPages() 58 th.AssertNoErr(t, err) 59 60 allAddresses, err := servers.ExtractAddresses(allAddressPages) 61 th.AssertNoErr(t, err) 62 63 for network, address := range allAddresses { 64 t.Logf("Addresses on %s: %+v", network, address) 65 } 66 67 allInterfacePages, err := attachinterfaces.List(client, server.ID).AllPages() 68 th.AssertNoErr(t, err) 69 70 allInterfaces, err := attachinterfaces.ExtractInterfaces(allInterfacePages) 71 th.AssertNoErr(t, err) 72 73 for _, iface := range allInterfaces { 74 t.Logf("Interfaces: %+v", iface) 75 } 76 77 allNetworkAddressPages, err := servers.ListAddressesByNetwork(client, server.ID, choices.NetworkName).AllPages() 78 th.AssertNoErr(t, err) 79 80 allNetworkAddresses, err := servers.ExtractNetworkAddresses(allNetworkAddressPages) 81 th.AssertNoErr(t, err) 82 83 t.Logf("Addresses on %s:", choices.NetworkName) 84 for _, address := range allNetworkAddresses { 85 t.Logf("%+v", address) 86 } 87 } 88 89 func TestServersWithExtensionsCreateDestroy(t *testing.T) { 90 clients.RequireLong(t) 91 92 var extendedServer struct { 93 servers.Server 94 availabilityzones.ServerAvailabilityZoneExt 95 extendedstatus.ServerExtendedStatusExt 96 serverusage.UsageExt 97 } 98 99 client, err := clients.NewComputeV2Client() 100 th.AssertNoErr(t, err) 101 102 server, err := CreateServer(t, client) 103 th.AssertNoErr(t, err) 104 defer DeleteServer(t, client, server) 105 106 err = servers.Get(client, server.ID).ExtractInto(&extendedServer) 107 th.AssertNoErr(t, err) 108 tools.PrintResource(t, extendedServer) 109 110 th.AssertEquals(t, extendedServer.AvailabilityZone, "nova") 111 th.AssertEquals(t, int(extendedServer.PowerState), extendedstatus.RUNNING) 112 th.AssertEquals(t, extendedServer.TaskState, "") 113 th.AssertEquals(t, extendedServer.VmState, "active") 114 th.AssertEquals(t, extendedServer.LaunchedAt.IsZero(), false) 115 th.AssertEquals(t, extendedServer.TerminatedAt.IsZero(), true) 116 } 117 118 func TestServersWithoutImageRef(t *testing.T) { 119 client, err := clients.NewComputeV2Client() 120 th.AssertNoErr(t, err) 121 122 server, err := CreateServerWithoutImageRef(t, client) 123 if err != nil { 124 if err400, ok := err.(*gophercloud.ErrUnexpectedResponseCode); ok { 125 if !strings.Contains(string(err400.Body), "Missing imageRef attribute") { 126 defer DeleteServer(t, client, server) 127 } 128 } 129 } 130 } 131 132 func TestServersUpdate(t *testing.T) { 133 clients.RequireLong(t) 134 135 client, err := clients.NewComputeV2Client() 136 th.AssertNoErr(t, err) 137 138 server, err := CreateServer(t, client) 139 th.AssertNoErr(t, err) 140 defer DeleteServer(t, client, server) 141 142 alternateName := tools.RandomString("ACPTTEST", 16) 143 for alternateName == server.Name { 144 alternateName = tools.RandomString("ACPTTEST", 16) 145 } 146 147 t.Logf("Attempting to rename the server to %s.", alternateName) 148 149 updateOpts := servers.UpdateOpts{ 150 Name: alternateName, 151 } 152 153 updated, err := servers.Update(client, server.ID, updateOpts).Extract() 154 th.AssertNoErr(t, err) 155 156 th.AssertEquals(t, updated.ID, server.ID) 157 158 err = tools.WaitFor(func() (bool, error) { 159 latest, err := servers.Get(client, updated.ID).Extract() 160 if err != nil { 161 return false, err 162 } 163 164 return latest.Name == alternateName, nil 165 }) 166 } 167 168 func TestServersMetadata(t *testing.T) { 169 clients.RequireLong(t) 170 171 client, err := clients.NewComputeV2Client() 172 th.AssertNoErr(t, err) 173 174 server, err := CreateServer(t, client) 175 th.AssertNoErr(t, err) 176 defer DeleteServer(t, client, server) 177 178 tools.PrintResource(t, server) 179 180 metadata, err := servers.UpdateMetadata(client, server.ID, servers.MetadataOpts{ 181 "foo": "bar", 182 "this": "that", 183 }).Extract() 184 th.AssertNoErr(t, err) 185 t.Logf("UpdateMetadata result: %+v\n", metadata) 186 187 server, err = servers.Get(client, server.ID).Extract() 188 th.AssertNoErr(t, err) 189 190 tools.PrintResource(t, server) 191 192 expectedMetadata := map[string]string{ 193 "abc": "def", 194 "foo": "bar", 195 "this": "that", 196 } 197 th.AssertDeepEquals(t, expectedMetadata, server.Metadata) 198 199 err = servers.DeleteMetadatum(client, server.ID, "foo").ExtractErr() 200 th.AssertNoErr(t, err) 201 202 server, err = servers.Get(client, server.ID).Extract() 203 th.AssertNoErr(t, err) 204 205 tools.PrintResource(t, server) 206 207 expectedMetadata = map[string]string{ 208 "abc": "def", 209 "this": "that", 210 } 211 th.AssertDeepEquals(t, expectedMetadata, server.Metadata) 212 213 metadata, err = servers.CreateMetadatum(client, server.ID, servers.MetadatumOpts{ 214 "foo": "baz", 215 }).Extract() 216 th.AssertNoErr(t, err) 217 t.Logf("CreateMetadatum result: %+v\n", metadata) 218 219 server, err = servers.Get(client, server.ID).Extract() 220 th.AssertNoErr(t, err) 221 222 tools.PrintResource(t, server) 223 224 expectedMetadata = map[string]string{ 225 "abc": "def", 226 "this": "that", 227 "foo": "baz", 228 } 229 th.AssertDeepEquals(t, expectedMetadata, server.Metadata) 230 231 metadata, err = servers.Metadatum(client, server.ID, "foo").Extract() 232 th.AssertNoErr(t, err) 233 t.Logf("Metadatum result: %+v\n", metadata) 234 th.AssertEquals(t, "baz", metadata["foo"]) 235 236 metadata, err = servers.Metadata(client, server.ID).Extract() 237 th.AssertNoErr(t, err) 238 t.Logf("Metadata result: %+v\n", metadata) 239 240 th.AssertDeepEquals(t, expectedMetadata, metadata) 241 242 metadata, err = servers.ResetMetadata(client, server.ID, servers.MetadataOpts{}).Extract() 243 th.AssertNoErr(t, err) 244 t.Logf("ResetMetadata result: %+v\n", metadata) 245 th.AssertDeepEquals(t, map[string]string{}, metadata) 246 } 247 248 func TestServersActionChangeAdminPassword(t *testing.T) { 249 clients.RequireLong(t) 250 clients.RequireGuestAgent(t) 251 252 client, err := clients.NewComputeV2Client() 253 th.AssertNoErr(t, err) 254 255 server, err := CreateServer(t, client) 256 th.AssertNoErr(t, err) 257 defer DeleteServer(t, client, server) 258 259 randomPassword := tools.MakeNewPassword(server.AdminPass) 260 res := servers.ChangeAdminPassword(client, server.ID, randomPassword) 261 th.AssertNoErr(t, res.Err) 262 263 if err = WaitForComputeStatus(client, server, "PASSWORD"); err != nil { 264 t.Fatal(err) 265 } 266 267 if err = WaitForComputeStatus(client, server, "ACTIVE"); err != nil { 268 t.Fatal(err) 269 } 270 } 271 272 func TestServersActionReboot(t *testing.T) { 273 clients.RequireLong(t) 274 275 client, err := clients.NewComputeV2Client() 276 th.AssertNoErr(t, err) 277 278 server, err := CreateServer(t, client) 279 th.AssertNoErr(t, err) 280 defer DeleteServer(t, client, server) 281 282 rebootOpts := servers.RebootOpts{ 283 Type: servers.SoftReboot, 284 } 285 286 t.Logf("Attempting reboot of server %s", server.ID) 287 res := servers.Reboot(client, server.ID, rebootOpts) 288 th.AssertNoErr(t, res.Err) 289 290 if err = WaitForComputeStatus(client, server, "REBOOT"); err != nil { 291 t.Fatal(err) 292 } 293 294 if err = WaitForComputeStatus(client, server, "ACTIVE"); err != nil { 295 t.Fatal(err) 296 } 297 } 298 299 func TestServersActionRebuild(t *testing.T) { 300 clients.RequireLong(t) 301 302 client, err := clients.NewComputeV2Client() 303 th.AssertNoErr(t, err) 304 305 choices, err := clients.AcceptanceTestChoicesFromEnv() 306 th.AssertNoErr(t, err) 307 308 server, err := CreateServer(t, client) 309 th.AssertNoErr(t, err) 310 defer DeleteServer(t, client, server) 311 312 t.Logf("Attempting to rebuild server %s", server.ID) 313 314 rebuildOpts := servers.RebuildOpts{ 315 Name: tools.RandomString("ACPTTEST", 16), 316 AdminPass: tools.MakeNewPassword(server.AdminPass), 317 ImageRef: choices.ImageID, 318 } 319 320 rebuilt, err := servers.Rebuild(client, server.ID, rebuildOpts).Extract() 321 th.AssertNoErr(t, err) 322 323 th.AssertEquals(t, rebuilt.ID, server.ID) 324 325 if err = WaitForComputeStatus(client, rebuilt, "REBUILD"); err != nil { 326 t.Fatal(err) 327 } 328 329 if err = WaitForComputeStatus(client, rebuilt, "ACTIVE"); err != nil { 330 t.Fatal(err) 331 } 332 } 333 334 func TestServersActionResizeConfirm(t *testing.T) { 335 clients.RequireLong(t) 336 337 choices, err := clients.AcceptanceTestChoicesFromEnv() 338 th.AssertNoErr(t, err) 339 340 client, err := clients.NewComputeV2Client() 341 th.AssertNoErr(t, err) 342 343 server, err := CreateServer(t, client) 344 th.AssertNoErr(t, err) 345 defer DeleteServer(t, client, server) 346 347 t.Logf("Attempting to resize server %s", server.ID) 348 ResizeServer(t, client, server) 349 350 t.Logf("Attempting to confirm resize for server %s", server.ID) 351 if res := servers.ConfirmResize(client, server.ID); res.Err != nil { 352 t.Fatal(res.Err) 353 } 354 355 if err = WaitForComputeStatus(client, server, "ACTIVE"); err != nil { 356 t.Fatal(err) 357 } 358 359 server, err = servers.Get(client, server.ID).Extract() 360 th.AssertNoErr(t, err) 361 362 th.AssertEquals(t, server.Flavor["id"], choices.FlavorIDResize) 363 } 364 365 func TestServersActionResizeRevert(t *testing.T) { 366 clients.RequireLong(t) 367 368 choices, err := clients.AcceptanceTestChoicesFromEnv() 369 th.AssertNoErr(t, err) 370 371 client, err := clients.NewComputeV2Client() 372 th.AssertNoErr(t, err) 373 374 server, err := CreateServer(t, client) 375 th.AssertNoErr(t, err) 376 defer DeleteServer(t, client, server) 377 378 t.Logf("Attempting to resize server %s", server.ID) 379 ResizeServer(t, client, server) 380 381 t.Logf("Attempting to revert resize for server %s", server.ID) 382 if res := servers.RevertResize(client, server.ID); res.Err != nil { 383 t.Fatal(res.Err) 384 } 385 386 if err = WaitForComputeStatus(client, server, "ACTIVE"); err != nil { 387 t.Fatal(err) 388 } 389 390 server, err = servers.Get(client, server.ID).Extract() 391 th.AssertNoErr(t, err) 392 393 th.AssertEquals(t, server.Flavor["id"], choices.FlavorID) 394 } 395 396 func TestServersActionPause(t *testing.T) { 397 clients.RequireLong(t) 398 399 client, err := clients.NewComputeV2Client() 400 th.AssertNoErr(t, err) 401 402 server, err := CreateServer(t, client) 403 th.AssertNoErr(t, err) 404 defer DeleteServer(t, client, server) 405 406 t.Logf("Attempting to pause server %s", server.ID) 407 err = pauseunpause.Pause(client, server.ID).ExtractErr() 408 th.AssertNoErr(t, err) 409 410 err = WaitForComputeStatus(client, server, "PAUSED") 411 th.AssertNoErr(t, err) 412 413 err = pauseunpause.Unpause(client, server.ID).ExtractErr() 414 th.AssertNoErr(t, err) 415 416 err = WaitForComputeStatus(client, server, "ACTIVE") 417 th.AssertNoErr(t, err) 418 } 419 420 func TestServersActionSuspend(t *testing.T) { 421 clients.RequireLong(t) 422 423 client, err := clients.NewComputeV2Client() 424 th.AssertNoErr(t, err) 425 426 server, err := CreateServer(t, client) 427 th.AssertNoErr(t, err) 428 defer DeleteServer(t, client, server) 429 430 t.Logf("Attempting to suspend server %s", server.ID) 431 err = suspendresume.Suspend(client, server.ID).ExtractErr() 432 th.AssertNoErr(t, err) 433 434 err = WaitForComputeStatus(client, server, "SUSPENDED") 435 th.AssertNoErr(t, err) 436 437 err = suspendresume.Resume(client, server.ID).ExtractErr() 438 th.AssertNoErr(t, err) 439 440 err = WaitForComputeStatus(client, server, "ACTIVE") 441 th.AssertNoErr(t, err) 442 } 443 444 func TestServersActionLock(t *testing.T) { 445 clients.RequireLong(t) 446 clients.RequireNonAdmin(t) 447 448 client, err := clients.NewComputeV2Client() 449 th.AssertNoErr(t, err) 450 451 server, err := CreateServer(t, client) 452 th.AssertNoErr(t, err) 453 defer DeleteServer(t, client, server) 454 455 t.Logf("Attempting to Lock server %s", server.ID) 456 err = lockunlock.Lock(client, server.ID).ExtractErr() 457 th.AssertNoErr(t, err) 458 459 t.Logf("Attempting to delete locked server %s", server.ID) 460 err = servers.Delete(client, server.ID).ExtractErr() 461 th.AssertEquals(t, err != nil, true) 462 463 t.Logf("Attempting to unlock server %s", server.ID) 464 err = lockunlock.Unlock(client, server.ID).ExtractErr() 465 th.AssertNoErr(t, err) 466 467 err = WaitForComputeStatus(client, server, "ACTIVE") 468 th.AssertNoErr(t, err) 469 } 470 471 func TestServersConsoleOutput(t *testing.T) { 472 clients.RequireLong(t) 473 474 client, err := clients.NewComputeV2Client() 475 th.AssertNoErr(t, err) 476 477 server, err := CreateServer(t, client) 478 th.AssertNoErr(t, err) 479 defer DeleteServer(t, client, server) 480 481 outputOpts := &servers.ShowConsoleOutputOpts{ 482 Length: 4, 483 } 484 output, err := servers.ShowConsoleOutput(client, server.ID, outputOpts).Extract() 485 th.AssertNoErr(t, err) 486 487 tools.PrintResource(t, output) 488 } 489 490 func TestServersTags(t *testing.T) { 491 clients.RequireLong(t) 492 493 choices, err := clients.AcceptanceTestChoicesFromEnv() 494 th.AssertNoErr(t, err) 495 496 client, err := clients.NewComputeV2Client() 497 th.AssertNoErr(t, err) 498 client.Microversion = "2.52" 499 500 networkClient, err := clients.NewNetworkV2Client() 501 th.AssertNoErr(t, err) 502 503 networkID, err := networks.IDFromName(networkClient, choices.NetworkName) 504 th.AssertNoErr(t, err) 505 506 // Create server with tags. 507 server, err := CreateServerWithTags(t, client, networkID) 508 th.AssertNoErr(t, err) 509 defer DeleteServer(t, client, server) 510 511 // All the following calls should work with "2.26" microversion. 512 client.Microversion = "2.26" 513 514 // Check server tags in body. 515 serverWithTags, err := servers.Get(client, server.ID).Extract() 516 th.AssertNoErr(t, err) 517 th.AssertDeepEquals(t, []string{"tag1", "tag2"}, *serverWithTags.Tags) 518 519 // Check all tags. 520 allTags, err := tags.List(client, server.ID).Extract() 521 th.AssertNoErr(t, err) 522 th.AssertDeepEquals(t, []string{"tag1", "tag2"}, allTags) 523 524 // Check single tag. 525 exists, err := tags.Check(client, server.ID, "tag2").Extract() 526 th.AssertNoErr(t, err) 527 th.AssertEquals(t, true, exists) 528 529 // Add new tag. 530 newTags, err := tags.ReplaceAll(client, server.ID, tags.ReplaceAllOpts{Tags: []string{"tag3", "tag4"}}).Extract() 531 th.AssertNoErr(t, err) 532 th.AssertDeepEquals(t, []string{"tag3", "tag4"}, newTags) 533 534 // Add new single tag. 535 err = tags.Add(client, server.ID, "tag5").ExtractErr() 536 th.AssertNoErr(t, err) 537 538 // Check current tags. 539 newAllTags, err := tags.List(client, server.ID).Extract() 540 th.AssertNoErr(t, err) 541 th.AssertDeepEquals(t, []string{"tag3", "tag4", "tag5"}, newAllTags) 542 543 // Remove single tag. 544 err = tags.Delete(client, server.ID, "tag4").ExtractErr() 545 th.AssertNoErr(t, err) 546 547 // Check that tag doesn't exist anymore. 548 exists, err = tags.Check(client, server.ID, "tag4").Extract() 549 th.AssertNoErr(t, err) 550 th.AssertEquals(t, false, exists) 551 552 // Remove all tags. 553 err = tags.DeleteAll(client, server.ID).ExtractErr() 554 th.AssertNoErr(t, err) 555 556 // Check that there are no more tags. 557 currentTags, err := tags.List(client, server.ID).Extract() 558 th.AssertNoErr(t, err) 559 th.AssertEquals(t, 0, len(currentTags)) 560 } 561 562 func TestServersWithExtendedAttributesCreateDestroy(t *testing.T) { 563 clients.RequireLong(t) 564 clients.RequireAdmin(t) 565 566 client, err := clients.NewComputeV2Client() 567 th.AssertNoErr(t, err) 568 client.Microversion = "2.3" 569 570 server, err := CreateServer(t, client) 571 th.AssertNoErr(t, err) 572 defer DeleteServer(t, client, server) 573 574 type serverAttributesExt struct { 575 servers.Server 576 extendedserverattributes.ServerAttributesExt 577 } 578 var serverWithAttributesExt serverAttributesExt 579 580 err = servers.Get(client, server.ID).ExtractInto(&serverWithAttributesExt) 581 th.AssertNoErr(t, err) 582 583 t.Logf("Server With Extended Attributes: %#v", serverWithAttributesExt) 584 585 th.AssertEquals(t, *serverWithAttributesExt.ReservationID != "", true) 586 th.AssertEquals(t, *serverWithAttributesExt.LaunchIndex, 0) 587 th.AssertEquals(t, *serverWithAttributesExt.RAMDiskID == "", true) 588 th.AssertEquals(t, *serverWithAttributesExt.KernelID == "", true) 589 th.AssertEquals(t, *serverWithAttributesExt.Hostname != "", true) 590 th.AssertEquals(t, *serverWithAttributesExt.RootDeviceName != "", true) 591 th.AssertEquals(t, serverWithAttributesExt.Userdata == nil, true) 592 } 593 594 func TestServerNoNetworkCreateDestroy(t *testing.T) { 595 clients.RequireLong(t) 596 597 client, err := clients.NewComputeV2Client() 598 th.AssertNoErr(t, err) 599 600 choices, err := clients.AcceptanceTestChoicesFromEnv() 601 th.AssertNoErr(t, err) 602 603 client.Microversion = "2.37" 604 605 server, err := CreateServerNoNetwork(t, client) 606 th.AssertNoErr(t, err) 607 defer DeleteServer(t, client, server) 608 609 allPages, err := servers.List(client, servers.ListOpts{}).AllPages() 610 th.AssertNoErr(t, err) 611 612 allServers, err := servers.ExtractServers(allPages) 613 th.AssertNoErr(t, err) 614 615 var found bool 616 for _, s := range allServers { 617 tools.PrintResource(t, server) 618 619 if s.ID == server.ID { 620 found = true 621 } 622 } 623 624 th.AssertEquals(t, found, true) 625 626 allAddressPages, err := servers.ListAddresses(client, server.ID).AllPages() 627 th.AssertNoErr(t, err) 628 629 allAddresses, err := servers.ExtractAddresses(allAddressPages) 630 th.AssertNoErr(t, err) 631 632 for network, address := range allAddresses { 633 t.Logf("Addresses on %s: %+v", network, address) 634 } 635 636 allInterfacePages, err := attachinterfaces.List(client, server.ID).AllPages() 637 th.AssertNoErr(t, err) 638 639 allInterfaces, err := attachinterfaces.ExtractInterfaces(allInterfacePages) 640 th.AssertNoErr(t, err) 641 642 for _, iface := range allInterfaces { 643 t.Logf("Interfaces: %+v", iface) 644 } 645 646 _, err = servers.ListAddressesByNetwork(client, server.ID, choices.NetworkName).AllPages() 647 if err == nil { 648 t.Fatalf("Instance must not be a member of specified network") 649 } 650 }