github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/openstack/baremetal/v1/nodes/testing/fixtures_test.go (about) 1 package testing 2 3 import ( 4 "fmt" 5 "net/http" 6 "testing" 7 "time" 8 9 inventorytest "github.com/vnpaycloud-console/gophercloud/v2/openstack/baremetal/inventory/testing" 10 "github.com/vnpaycloud-console/gophercloud/v2/openstack/baremetal/v1/nodes" 11 th "github.com/vnpaycloud-console/gophercloud/v2/testhelper" 12 "github.com/vnpaycloud-console/gophercloud/v2/testhelper/client" 13 ) 14 15 // NodeListBody contains the canned body of a nodes.List response, without detail. 16 const NodeListBody = ` 17 { 18 "nodes": [ 19 { 20 "instance_uuid": null, 21 "links": [ 22 { 23 "href": "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e", 24 "rel": "self" 25 }, 26 { 27 "href": "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e", 28 "rel": "bookmark" 29 } 30 ], 31 "maintenance": false, 32 "name": "foo", 33 "power_state": null, 34 "provision_state": "enroll" 35 }, 36 { 37 "instance_uuid": null, 38 "links": [ 39 { 40 "href": "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", 41 "rel": "self" 42 }, 43 { 44 "href": "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", 45 "rel": "bookmark" 46 } 47 ], 48 "maintenance": false, 49 "name": "bar", 50 "power_state": null, 51 "provision_state": "enroll" 52 }, 53 { 54 "instance_uuid": null, 55 "links": [ 56 { 57 "href": "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474", 58 "rel": "self" 59 }, 60 { 61 "href": "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474", 62 "rel": "bookmark" 63 } 64 ], 65 "maintenance": false, 66 "name": "baz", 67 "power_state": null, 68 "provision_state": "enroll" 69 } 70 ] 71 } 72 ` 73 74 // NodeListDetailBody contains the canned body of a nodes.ListDetail response. 75 const NodeListDetailBody = ` 76 { 77 "nodes": [ 78 { 79 "automated_clean": null, 80 "bios_interface": "no-bios", 81 "boot_interface": "pxe", 82 "chassis_uuid": null, 83 "clean_step": {}, 84 "conductor_group": "", 85 "console_enabled": false, 86 "console_interface": "no-console", 87 "created_at": "2019-01-31T19:59:28+00:00", 88 "deploy_interface": "iscsi", 89 "deploy_step": {}, 90 "disable_power_off": false, 91 "driver": "ipmi", 92 "driver_info": { 93 "ipmi_port": "6230", 94 "ipmi_username": "admin", 95 "deploy_kernel": "http://172.22.0.1/images/tinyipa-stable-rocky.vmlinuz", 96 "ipmi_address": "192.168.122.1", 97 "deploy_ramdisk": "http://172.22.0.1/images/tinyipa-stable-rocky.gz", 98 "ipmi_password": "admin" 99 100 }, 101 "driver_internal_info": {}, 102 "extra": {}, 103 "fault": null, 104 "firmware_interface": "no-firmware", 105 "inspect_interface": "no-inspect", 106 "inspection_finished_at": null, 107 "inspection_started_at": null, 108 "instance_info": {}, 109 "instance_uuid": null, 110 "last_error": null, 111 "links": [ 112 { 113 "href": "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e", 114 "rel": "self" 115 }, 116 { 117 "href": "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e", 118 "rel": "bookmark" 119 } 120 ], 121 "maintenance": false, 122 "maintenance_reason": null, 123 "management_interface": "ipmitool", 124 "name": "foo", 125 "network_interface": "flat", 126 "portgroups": [ 127 { 128 "href": "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/portgroups", 129 "rel": "self" 130 }, 131 { 132 "href": "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/portgroups", 133 "rel": "bookmark" 134 } 135 ], 136 "ports": [ 137 { 138 "href": "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/ports", 139 "rel": "self" 140 }, 141 { 142 "href": "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/ports", 143 "rel": "bookmark" 144 } 145 ], 146 "power_interface": "ipmitool", 147 "power_state": null, 148 "properties": {}, 149 "provision_state": "enroll", 150 "provision_updated_at": "2019-02-15T17:21:29+00:00", 151 "raid_config": {}, 152 "raid_interface": "no-raid", 153 "retired": false, 154 "retired_reason": "No longer needed", 155 "rescue_interface": "no-rescue", 156 "reservation": null, 157 "resource_class": null, 158 "states": [ 159 { 160 "href": "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/states", 161 "rel": "self" 162 }, 163 { 164 "href": "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/states", 165 "rel": "bookmark" 166 } 167 ], 168 "storage_interface": "noop", 169 "target_power_state": null, 170 "target_provision_state": null, 171 "target_raid_config": {}, 172 "traits": [], 173 "updated_at": "2019-02-15T19:59:29+00:00", 174 "uuid": "d2630783-6ec8-4836-b556-ab427c4b581e", 175 "vendor_interface": "ipmitool", 176 "volume": [ 177 { 178 "href": "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/volume", 179 "rel": "self" 180 }, 181 { 182 "href": "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/volume", 183 "rel": "bookmark" 184 } 185 ] 186 }, 187 { 188 "automated_clean": null, 189 "bios_interface": "no-bios", 190 "boot_interface": "pxe", 191 "chassis_uuid": null, 192 "clean_step": {}, 193 "conductor_group": "", 194 "console_enabled": false, 195 "console_interface": "no-console", 196 "created_at": "2019-01-31T19:59:29+00:00", 197 "deploy_interface": "iscsi", 198 "deploy_step": {}, 199 "disable_power_off": false, 200 "driver": "ipmi", 201 "driver_info": {}, 202 "driver_internal_info": {}, 203 "extra": {}, 204 "fault": null, 205 "firmware_interface": "no-firmware", 206 "inspect_interface": "no-inspect", 207 "inspection_finished_at": "2023-02-02T14:45:59.705249Z", 208 "inspection_started_at": "2023-02-02T14:35:59.682403Z", 209 "instance_info": {}, 210 "instance_uuid": null, 211 "last_error": null, 212 "links": [ 213 { 214 "href": "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", 215 "rel": "self" 216 }, 217 { 218 "href": "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", 219 "rel": "bookmark" 220 } 221 ], 222 "maintenance": false, 223 "maintenance_reason": null, 224 "management_interface": "ipmitool", 225 "name": "bar", 226 "network_interface": "flat", 227 "portgroups": [ 228 { 229 "href": "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/portgroups", 230 "rel": "self" 231 }, 232 { 233 "href": "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/portgroups", 234 "rel": "bookmark" 235 } 236 ], 237 "ports": [ 238 { 239 "href": "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/ports", 240 "rel": "self" 241 }, 242 { 243 "href": "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/ports", 244 "rel": "bookmark" 245 } 246 ], 247 "power_interface": "ipmitool", 248 "power_state": null, 249 "properties": {}, 250 "provision_state": "available", 251 "provision_updated_at": null, 252 "raid_config": {}, 253 "raid_interface": "no-raid", 254 "retired": false, 255 "retired_reason": "No longer needed", 256 "rescue_interface": "no-rescue", 257 "reservation": null, 258 "resource_class": null, 259 "states": [ 260 { 261 "href": "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/states", 262 "rel": "self" 263 }, 264 { 265 "href": "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/states", 266 "rel": "bookmark" 267 } 268 ], 269 "storage_interface": "noop", 270 "target_power_state": null, 271 "target_provision_state": null, 272 "target_raid_config": {}, 273 "traits": [], 274 "updated_at": "2019-02-15T19:59:29+00:00", 275 "uuid": "08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", 276 "vendor_interface": "ipmitool", 277 "volume": [ 278 { 279 "href": "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/volume", 280 "rel": "self" 281 }, 282 { 283 "href": "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/volume", 284 "rel": "bookmark" 285 } 286 ] 287 }, 288 { 289 "automated_clean": null, 290 "bios_interface": "no-bios", 291 "boot_interface": "pxe", 292 "chassis_uuid": null, 293 "clean_step": {}, 294 "conductor_group": "", 295 "console_enabled": false, 296 "console_interface": "no-console", 297 "created_at": "2019-01-31T19:59:30+00:00", 298 "deploy_interface": "iscsi", 299 "deploy_step": {}, 300 "disable_power_off": true, 301 "driver": "ipmi", 302 "driver_info": {}, 303 "driver_internal_info": {}, 304 "extra": {}, 305 "fault": null, 306 "firmware_interface": "no-firmware", 307 "inspect_interface": "no-inspect", 308 "inspection_finished_at": null, 309 "inspection_started_at": null, 310 "instance_info": {}, 311 "instance_uuid": null, 312 "last_error": null, 313 "links": [ 314 { 315 "href": "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474", 316 "rel": "self" 317 }, 318 { 319 "href": "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474", 320 "rel": "bookmark" 321 } 322 ], 323 "maintenance": false, 324 "maintenance_reason": null, 325 "management_interface": "ipmitool", 326 "name": "baz", 327 "network_interface": "flat", 328 "portgroups": [ 329 { 330 "href": "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/portgroups", 331 "rel": "self" 332 }, 333 { 334 "href": "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/portgroups", 335 "rel": "bookmark" 336 } 337 ], 338 "ports": [ 339 { 340 "href": "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/ports", 341 "rel": "self" 342 }, 343 { 344 "href": "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/ports", 345 "rel": "bookmark" 346 } 347 ], 348 "power_interface": "ipmitool", 349 "power_state": null, 350 "properties": {}, 351 "provision_state": "enroll", 352 "provision_updated_at": null, 353 "raid_config": {}, 354 "raid_interface": "no-raid", 355 "retired": false, 356 "retired_reason": "No longer needed", 357 "rescue_interface": "no-rescue", 358 "reservation": null, 359 "resource_class": null, 360 "states": [ 361 { 362 "href": "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/states", 363 "rel": "self" 364 }, 365 { 366 "href": "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/states", 367 "rel": "bookmark" 368 } 369 ], 370 "storage_interface": "noop", 371 "target_power_state": null, 372 "target_provision_state": null, 373 "target_raid_config": {}, 374 "traits": [], 375 "updated_at": "2019-02-15T19:59:29+00:00", 376 "uuid": "c9afd385-5d89-4ecb-9e1c-68194da6b474", 377 "vendor_interface": "ipmitool", 378 "volume": [ 379 { 380 "href": "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/volume", 381 "rel": "self" 382 }, 383 { 384 "href": "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/volume", 385 "rel": "bookmark" 386 } 387 ] 388 } 389 ] 390 } 391 ` 392 393 // SingleNodeBody is the canned body of a Get request on an existing node. 394 const SingleNodeBody = ` 395 { 396 "automated_clean": null, 397 "bios_interface": "no-bios", 398 "boot_interface": "pxe", 399 "chassis_uuid": null, 400 "clean_step": {}, 401 "conductor_group": "", 402 "console_enabled": false, 403 "console_interface": "no-console", 404 "created_at": "2019-01-31T19:59:28+00:00", 405 "deploy_interface": "iscsi", 406 "deploy_step": {}, 407 "driver": "ipmi", 408 "driver_info": { 409 "ipmi_port": "6230", 410 "ipmi_username": "admin", 411 "deploy_kernel": "http://172.22.0.1/images/tinyipa-stable-rocky.vmlinuz", 412 "ipmi_address": "192.168.122.1", 413 "deploy_ramdisk": "http://172.22.0.1/images/tinyipa-stable-rocky.gz", 414 "ipmi_password": "admin" 415 }, 416 "driver_internal_info": {}, 417 "extra": {}, 418 "fault": null, 419 "firmware_interface": "no-firmware", 420 "inspect_interface": "no-inspect", 421 "inspection_finished_at": null, 422 "inspection_started_at": null, 423 "instance_info": {}, 424 "instance_uuid": null, 425 "last_error": null, 426 "links": [ 427 { 428 "href": "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e", 429 "rel": "self" 430 }, 431 { 432 "href": "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e", 433 "rel": "bookmark" 434 } 435 ], 436 "maintenance": false, 437 "maintenance_reason": null, 438 "management_interface": "ipmitool", 439 "name": "foo", 440 "network_interface": "flat", 441 "portgroups": [ 442 { 443 "href": "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/portgroups", 444 "rel": "self" 445 }, 446 { 447 "href": "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/portgroups", 448 "rel": "bookmark" 449 } 450 ], 451 "ports": [ 452 { 453 "href": "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/ports", 454 "rel": "self" 455 }, 456 { 457 "href": "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/ports", 458 "rel": "bookmark" 459 } 460 ], 461 "power_interface": "ipmitool", 462 "power_state": null, 463 "properties": {}, 464 "provision_state": "enroll", 465 "provision_updated_at": "2019-02-15T17:21:29+00:00", 466 "raid_config": {}, 467 "raid_interface": "no-raid", 468 "retired": false, 469 "retired_reason": "No longer needed", 470 "rescue_interface": "no-rescue", 471 "reservation": null, 472 "resource_class": null, 473 "states": [ 474 { 475 "href": "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/states", 476 "rel": "self" 477 }, 478 { 479 "href": "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/states", 480 "rel": "bookmark" 481 } 482 ], 483 "storage_interface": "noop", 484 "target_power_state": null, 485 "target_provision_state": null, 486 "target_raid_config": {}, 487 "traits": [], 488 "updated_at": "2019-02-15T19:59:29+00:00", 489 "uuid": "d2630783-6ec8-4836-b556-ab427c4b581e", 490 "vendor_interface": "ipmitool", 491 "volume": [ 492 { 493 "href": "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/volume", 494 "rel": "self" 495 }, 496 { 497 "href": "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/volume", 498 "rel": "bookmark" 499 } 500 ] 501 } 502 ` 503 504 const NodeValidationBody = ` 505 { 506 "bios": { 507 "reason": "Driver ipmi does not support bios (disabled or not implemented).", 508 "result": false 509 }, 510 "boot": { 511 "reason": "Cannot validate image information for node a62b8495-52e2-407b-b3cb-62775d04c2b8 because one or more parameters are missing from its instance_info and insufficent information is present to boot from a remote volume. Missing are: ['ramdisk', 'kernel', 'image_source']", 512 "result": false 513 }, 514 "console": { 515 "reason": "Driver ipmi does not support console (disabled or not implemented).", 516 "result": false 517 }, 518 "deploy": { 519 "reason": "Cannot validate image information for node a62b8495-52e2-407b-b3cb-62775d04c2b8 because one or more parameters are missing from its instance_info and insufficent information is present to boot from a remote volume. Missing are: ['ramdisk', 'kernel', 'image_source']", 520 "result": false 521 }, 522 "firmware": { 523 "reason": "Driver ipmi does not support firmware (disabled or not implemented).", 524 "result": false 525 }, 526 "inspect": { 527 "reason": "Driver ipmi does not support inspect (disabled or not implemented).", 528 "result": false 529 }, 530 "management": { 531 "result": true 532 }, 533 "network": { 534 "result": true 535 }, 536 "power": { 537 "result": true 538 }, 539 "raid": { 540 "reason": "Driver ipmi does not support raid (disabled or not implemented).", 541 "result": false 542 }, 543 "rescue": { 544 "reason": "Driver ipmi does not support rescue (disabled or not implemented).", 545 "result": false 546 }, 547 "storage": { 548 "result": true 549 } 550 } 551 ` 552 553 const NodeBootDeviceBody = ` 554 { 555 "boot_device":"pxe", 556 "persistent":false 557 } 558 ` 559 560 const NodeSupportedBootDeviceBody = ` 561 { 562 "supported_boot_devices": [ 563 "pxe", 564 "disk" 565 ] 566 } 567 ` 568 569 const NodeProvisionStateActiveBody = ` 570 { 571 "target": "active", 572 "configdrive": "http://127.0.0.1/images/test-node-config-drive.iso.gz" 573 } 574 ` 575 576 const NodeProvisionStateActiveBodyWithSteps = ` 577 { 578 "target": "active", 579 "deploy_steps": [ 580 { 581 "interface": "deploy", 582 "step": "inject_files", 583 "priority": 50, 584 "args": { 585 "files": [] 586 } 587 } 588 ] 589 } 590 ` 591 592 const NodeProvisionStateCleanBody = ` 593 { 594 "target": "clean", 595 "clean_steps": [ 596 { 597 "interface": "deploy", 598 "step": "upgrade_firmware", 599 "args": { 600 "force": "True" 601 } 602 } 603 ] 604 } 605 ` 606 607 const NodeProvisionStateConfigDriveBody = ` 608 { 609 "target": "active", 610 "configdrive": { 611 "user_data": { 612 "ignition": { 613 "version": "2.2.0" 614 }, 615 "systemd": { 616 "units": [ 617 { 618 "enabled": true, 619 "name": "example.service" 620 } 621 ] 622 } 623 } 624 } 625 } 626 ` 627 628 const NodeProvisionStateServiceBody = ` 629 { 630 "target": "service", 631 "service_steps": [ 632 { 633 "interface": "bios", 634 "step": "apply_configuration", 635 "args": { 636 "settings": [] 637 } 638 } 639 ] 640 } 641 ` 642 643 const NodeBIOSSettingsBody = ` 644 { 645 "bios": [ 646 { 647 "name": "Proc1L2Cache", 648 "value": "10x256 KB" 649 }, 650 { 651 "name": "Proc1NumCores", 652 "value": "10" 653 }, 654 { 655 "name": "ProcVirtualization", 656 "value": "Enabled" 657 } 658 ] 659 } 660 ` 661 662 const NodeDetailBIOSSettingsBody = ` 663 { 664 "bios": [ 665 { 666 "created_at": "2021-05-11T21:33:44+00:00", 667 "updated_at": null, 668 "name": "Proc1L2Cache", 669 "value": "10x256 KB", 670 "attribute_type": "String", 671 "allowable_values": [], 672 "lower_bound": null, 673 "max_length": 16, 674 "min_length": 0, 675 "read_only": true, 676 "reset_required": null, 677 "unique": null, 678 "upper_bound": null, 679 "links": [ 680 { 681 "href": "http://ironic.example.com:6385/v1/nodes/d26115bf-1296-4ca8-8c86-6f310d8ec375/bios/Proc1L2Cache", 682 "rel": "self" 683 }, 684 { 685 "href": "http://ironic.example.com:6385/nodes/d26115bf-1296-4ca8-8c86-6f310d8ec375/bios/Proc1L2Cache", 686 "rel": "bookmark" 687 } 688 ] 689 }, 690 { 691 "created_at": "2021-05-11T21:33:44+00:00", 692 "updated_at": null, 693 "name": "Proc1NumCores", 694 "value": "10", 695 "attribute_type": "Integer", 696 "allowable_values": [], 697 "lower_bound": 0, 698 "max_length": null, 699 "min_length": null, 700 "read_only": true, 701 "reset_required": null, 702 "unique": null, 703 "upper_bound": 20, 704 "links": [ 705 { 706 "href": "http://ironic.example.com:6385/v1/nodes/d26115bf-1296-4ca8-8c86-6f310d8ec375/bios/Proc1NumCores", 707 "rel": "self" 708 }, 709 { 710 "href": "http://ironic.example.com:6385/nodes/d26115bf-1296-4ca8-8c86-6f310d8ec375/bios/Proc1NumCores", 711 "rel": "bookmark" 712 } 713 ] 714 }, 715 { 716 "created_at": "2021-05-11T21:33:44+00:00", 717 "updated_at": null, 718 "name": "ProcVirtualization", 719 "value": "Enabled", 720 "attribute_type": "Enumeration", 721 "allowable_values": [ 722 "Enabled", 723 "Disabled" 724 ], 725 "lower_bound": null, 726 "max_length": null, 727 "min_length": null, 728 "read_only": false, 729 "reset_required": null, 730 "unique": null, 731 "upper_bound": null, 732 "links": [ 733 { 734 "href": "http://ironic.example.com:6385/v1/nodes/d26115bf-1296-4ca8-8c86-6f310d8ec375/bios/ProcVirtualization", 735 "rel": "self" 736 }, 737 { 738 "href": "http://ironic.example.com:6385/nodes/d26115bf-1296-4ca8-8c86-6f310d8ec375/bios/ProcVirtualization", 739 "rel": "bookmark" 740 } 741 ] 742 } 743 ] 744 } 745 ` 746 747 const NodeSingleBIOSSettingBody = ` 748 { 749 "Setting": { 750 "name": "ProcVirtualization", 751 "value": "Enabled" 752 } 753 } 754 ` 755 756 const NodeVendorPassthruMethodsBody = ` 757 { 758 "create_subscription": { 759 "http_methods": [ 760 "POST" 761 ], 762 "async": false, 763 "description": "", 764 "attach": false, 765 "require_exclusive_lock": true 766 }, 767 "delete_subscription": { 768 "http_methods": [ 769 "DELETE" 770 ], 771 "async": false, 772 "description": "", 773 "attach": false, 774 "require_exclusive_lock": true 775 }, 776 "get_subscription": { 777 "http_methods": [ 778 "GET" 779 ], 780 "async": false, 781 "description": "", 782 "attach": false, 783 "require_exclusive_lock": true 784 }, 785 "get_all_subscriptions": { 786 "http_methods": [ 787 "GET" 788 ], 789 "async": false, 790 "description": "", 791 "attach": false, 792 "require_exclusive_lock": true 793 } 794 } 795 ` 796 797 const NodeGetAllSubscriptionsVnedorPassthruBody = ` 798 { 799 "@odata.context": "/redfish/v1/$metadata#EventDestinationCollection.EventDestinationCollection", 800 "@odata.id": "/redfish/v1/EventService/Subscriptions", 801 "@odata.type": "#EventDestinationCollection.EventDestinationCollection", 802 "Description": "List of Event subscriptions", 803 "Members": [ 804 { 805 "@odata.id": "/redfish/v1/EventService/Subscriptions/62dbd1b6-f637-11eb-b551-4cd98f20754c" 806 } 807 ], 808 "Members@odata.count": 1, 809 "Name": "Event Subscriptions Collection" 810 } 811 812 ` 813 814 const NodeGetSubscriptionVendorPassthruBody = ` 815 { 816 "Context": "Ironic", 817 "Destination": "https://192.168.0.1/EventReceiver.php", 818 "EventTypes": ["Alert"], 819 "Id": "62dbd1b6-f637-11eb-b551-4cd98f20754c", 820 "Protocol": "Redfish" 821 } 822 ` 823 824 const NodeCreateSubscriptionVendorPassthruAllParametersBody = ` 825 { 826 "Context": "gophercloud", 827 "Destination": "https://someurl", 828 "EventTypes": ["Alert"], 829 "HttpHeaders": [{"Context-Type":"application/json"}], 830 "Id": "eaa43e2-018a-424e-990a-cbf47c62ef80", 831 "Protocol": "Redfish" 832 } 833 ` 834 835 const NodeCreateSubscriptionVendorPassthruRequiredParametersBody = ` 836 { 837 "Context": "", 838 "Destination": "https://somedestinationurl", 839 "EventTypes": ["Alert"], 840 "Id": "344a3e2-978a-444e-990a-cbf47c62ef88", 841 "Protocol": "Redfish" 842 } 843 ` 844 845 const NodeSetMaintenanceBody = ` 846 { 847 "reason": "I'm tired" 848 } 849 ` 850 851 var NodeInventoryBody = fmt.Sprintf(` 852 { 853 "inventory": %s, 854 "plugin_data":{ 855 "macs":[ 856 "52:54:00:90:35:d6" 857 ], 858 "local_gb":10, 859 "cpu_arch":"x86_64", 860 "memory_mb":2048 861 } 862 } 863 `, inventorytest.InventorySample) 864 865 const NodeFirmwareListBody = ` 866 { 867 "firmware": [ 868 { 869 "created_at": "2023-10-03T18:30:00+00:00", 870 "updated_at": null, 871 "component": "bios", 872 "initial_version": "U30 v2.36 (07/16/2020)", 873 "current_version": "U30 v2.36 (07/16/2020)", 874 "last_version_flashed": null 875 }, 876 { 877 "created_at": "2023-10-03T18:30:00+00:00", 878 "updated_at": "2023-10-03T18:45:54+00:00", 879 "component": "bmc", 880 "initial_version": "iLO 5 v2.78", 881 "current_version": "iLO 5 v2.81", 882 "last_version_flashed": "iLO 5 v2.81" 883 } 884 ] 885 } 886 ` 887 888 const NodeVirtualMediaAttachBody = ` 889 { 890 "image_url": "https://example.com/image", 891 "device_type": "cdrom" 892 } 893 ` 894 895 const NodeVirtualMediaAttachBodyWithSource = ` 896 { 897 "image_url": "https://example.com/image", 898 "device_type": "cdrom", 899 "image_download_source": "http" 900 } 901 ` 902 903 var ( 904 createdAtFoo, _ = time.Parse(time.RFC3339, "2019-01-31T19:59:28+00:00") 905 createdAtBar, _ = time.Parse(time.RFC3339, "2019-01-31T19:59:29+00:00") 906 createdAtBaz, _ = time.Parse(time.RFC3339, "2019-01-31T19:59:30+00:00") 907 updatedAt, _ = time.Parse(time.RFC3339, "2019-02-15T19:59:29+00:00") 908 provisonUpdatedAt, _ = time.Parse(time.RFC3339, "2019-02-15T17:21:29+00:00") 909 910 NodeFoo = nodes.Node{ 911 UUID: "d2630783-6ec8-4836-b556-ab427c4b581e", 912 Name: "foo", 913 PowerState: "", 914 TargetPowerState: "", 915 ProvisionState: "enroll", 916 TargetProvisionState: "", 917 Maintenance: false, 918 MaintenanceReason: "", 919 Fault: "", 920 LastError: "", 921 Reservation: "", 922 Driver: "ipmi", 923 DriverInfo: map[string]any{ 924 "ipmi_port": "6230", 925 "ipmi_username": "admin", 926 "deploy_kernel": "http://172.22.0.1/images/tinyipa-stable-rocky.vmlinuz", 927 "ipmi_address": "192.168.122.1", 928 "deploy_ramdisk": "http://172.22.0.1/images/tinyipa-stable-rocky.gz", 929 "ipmi_password": "admin", 930 }, 931 DriverInternalInfo: map[string]any{}, 932 Properties: map[string]any{}, 933 InstanceInfo: map[string]any{}, 934 InstanceUUID: "", 935 ChassisUUID: "", 936 Extra: map[string]any{}, 937 ConsoleEnabled: false, 938 RAIDConfig: map[string]any{}, 939 TargetRAIDConfig: map[string]any{}, 940 CleanStep: map[string]any{}, 941 DeployStep: map[string]any{}, 942 Links: []nodes.Link{ 943 { 944 Href: "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e", 945 Rel: "self", 946 }, 947 { 948 Href: "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e", 949 Rel: "bookmark", 950 }, 951 }, 952 Ports: []nodes.Link{ 953 { 954 Href: "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/ports", 955 Rel: "self", 956 }, 957 { 958 Href: "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/ports", 959 Rel: "bookmark", 960 }, 961 }, 962 PortGroups: []nodes.Link{ 963 { 964 Href: "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/portgroups", 965 Rel: "self", 966 }, 967 { 968 Href: "http://ironic.example.com:6385/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/portgroups", 969 Rel: "bookmark"}, 970 }, 971 States: []nodes.Link{ 972 { 973 Href: "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/states", 974 Rel: "self", 975 }, 976 }, 977 ResourceClass: "", 978 BIOSInterface: "no-bios", 979 BootInterface: "pxe", 980 ConsoleInterface: "no-console", 981 DeployInterface: "iscsi", 982 InspectInterface: "no-inspect", 983 ManagementInterface: "ipmitool", 984 NetworkInterface: "flat", 985 PowerInterface: "ipmitool", 986 RAIDInterface: "no-raid", 987 RescueInterface: "no-rescue", 988 StorageInterface: "noop", 989 Traits: []string{}, 990 VendorInterface: "ipmitool", 991 Volume: []nodes.Link{ 992 { 993 Href: "http://ironic.example.com:6385/v1/nodes/d2630783-6ec8-4836-b556-ab427c4b581e/volume", 994 Rel: "self", 995 }, 996 }, 997 ConductorGroup: "", 998 ParentNode: "", 999 Protected: false, 1000 ProtectedReason: "", 1001 Owner: "", 1002 Lessee: "", 1003 Shard: "", 1004 Description: "", 1005 Conductor: "", 1006 AllocationUUID: "", 1007 Retired: false, 1008 RetiredReason: "No longer needed", 1009 NetworkData: map[string]interface{}(nil), 1010 AutomatedClean: nil, 1011 ServiceStep: map[string]interface{}(nil), 1012 FirmwareInterface: "no-firmware", 1013 ProvisionUpdatedAt: provisonUpdatedAt, 1014 InspectionStartedAt: nil, 1015 InspectionFinishedAt: nil, 1016 CreatedAt: createdAtFoo, 1017 UpdatedAt: updatedAt, 1018 } 1019 1020 NodeFooValidation = nodes.NodeValidation{ 1021 BIOS: nodes.DriverValidation{ 1022 Result: false, 1023 Reason: "Driver ipmi does not support bios (disabled or not implemented).", 1024 }, 1025 Boot: nodes.DriverValidation{ 1026 Result: false, 1027 Reason: "Cannot validate image information for node a62b8495-52e2-407b-b3cb-62775d04c2b8 because one or more parameters are missing from its instance_info and insufficent information is present to boot from a remote volume. Missing are: ['ramdisk', 'kernel', 'image_source']", 1028 }, 1029 Console: nodes.DriverValidation{ 1030 Result: false, 1031 Reason: "Driver ipmi does not support console (disabled or not implemented).", 1032 }, 1033 Deploy: nodes.DriverValidation{ 1034 Result: false, 1035 Reason: "Cannot validate image information for node a62b8495-52e2-407b-b3cb-62775d04c2b8 because one or more parameters are missing from its instance_info and insufficent information is present to boot from a remote volume. Missing are: ['ramdisk', 'kernel', 'image_source']", 1036 }, 1037 Firmware: nodes.DriverValidation{ 1038 Result: false, 1039 Reason: "Driver ipmi does not support firmware (disabled or not implemented).", 1040 }, 1041 Inspect: nodes.DriverValidation{ 1042 Result: false, 1043 Reason: "Driver ipmi does not support inspect (disabled or not implemented).", 1044 }, 1045 Management: nodes.DriverValidation{ 1046 Result: true, 1047 }, 1048 Network: nodes.DriverValidation{ 1049 Result: true, 1050 }, 1051 Power: nodes.DriverValidation{ 1052 Result: true, 1053 }, 1054 RAID: nodes.DriverValidation{ 1055 Result: false, 1056 Reason: "Driver ipmi does not support raid (disabled or not implemented).", 1057 }, 1058 Rescue: nodes.DriverValidation{ 1059 Result: false, 1060 Reason: "Driver ipmi does not support rescue (disabled or not implemented).", 1061 }, 1062 Storage: nodes.DriverValidation{ 1063 Result: true, 1064 }, 1065 } 1066 1067 NodeBootDevice = nodes.BootDeviceOpts{ 1068 BootDevice: "pxe", 1069 Persistent: false, 1070 } 1071 1072 NodeSupportedBootDevice = []string{ 1073 "pxe", 1074 "disk", 1075 } 1076 1077 InspectionStartedAt = time.Date(2023, time.February, 2, 14, 35, 59, 682403000, time.UTC) 1078 InspectionFinishedAt = time.Date(2023, time.February, 2, 14, 45, 59, 705249000, time.UTC) 1079 1080 NodeBar = nodes.Node{ 1081 UUID: "08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", 1082 Name: "bar", 1083 PowerState: "", 1084 TargetPowerState: "", 1085 ProvisionState: "available", 1086 TargetProvisionState: "", 1087 Maintenance: false, 1088 MaintenanceReason: "", 1089 Fault: "", 1090 LastError: "", 1091 Reservation: "", 1092 Driver: "ipmi", 1093 DriverInfo: map[string]any{}, 1094 DriverInternalInfo: map[string]any{}, 1095 Properties: map[string]any{}, 1096 InstanceInfo: map[string]any{}, 1097 InstanceUUID: "", 1098 ChassisUUID: "", 1099 Extra: map[string]any{}, 1100 ConsoleEnabled: false, 1101 RAIDConfig: map[string]any{}, 1102 TargetRAIDConfig: map[string]any{}, 1103 CleanStep: map[string]any{}, 1104 DeployStep: map[string]any{}, 1105 ResourceClass: "", 1106 BIOSInterface: "no-bios", 1107 BootInterface: "pxe", 1108 ConsoleInterface: "no-console", 1109 DeployInterface: "iscsi", 1110 FirmwareInterface: "no-firmware", 1111 InspectInterface: "no-inspect", 1112 ManagementInterface: "ipmitool", 1113 NetworkInterface: "flat", 1114 PowerInterface: "ipmitool", 1115 RAIDInterface: "no-raid", 1116 RescueInterface: "no-rescue", 1117 StorageInterface: "noop", 1118 Traits: []string{}, 1119 VendorInterface: "ipmitool", 1120 ConductorGroup: "", 1121 Protected: false, 1122 ProtectedReason: "", 1123 CreatedAt: createdAtBar, 1124 UpdatedAt: updatedAt, 1125 InspectionStartedAt: &InspectionStartedAt, 1126 InspectionFinishedAt: &InspectionFinishedAt, 1127 Retired: false, 1128 RetiredReason: "No longer needed", 1129 DisablePowerOff: false, 1130 Links: []nodes.Link{ 1131 {Href: "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", Rel: "self"}, 1132 {Href: "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662", Rel: "bookmark"}, 1133 }, 1134 Ports: []nodes.Link{ 1135 {Href: "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/ports", Rel: "self"}, 1136 {Href: "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/ports", Rel: "bookmark"}, 1137 }, 1138 PortGroups: []nodes.Link{ 1139 {Href: "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/portgroups", Rel: "self"}, 1140 {Href: "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/portgroups", Rel: "bookmark"}, 1141 }, 1142 States: []nodes.Link{ 1143 {Href: "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/states", Rel: "self"}, 1144 {Href: "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/states", Rel: "bookmark"}, 1145 }, 1146 Volume: []nodes.Link{ 1147 {Href: "http://ironic.example.com:6385/v1/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/volume", Rel: "self"}, 1148 {Href: "http://ironic.example.com:6385/nodes/08c84581-58f5-4ea2-a0c6-dd2e5d2b3662/volume", Rel: "bookmark"}, 1149 }, 1150 } 1151 1152 NodeBaz = nodes.Node{ 1153 UUID: "c9afd385-5d89-4ecb-9e1c-68194da6b474", 1154 Name: "baz", 1155 PowerState: "", 1156 TargetPowerState: "", 1157 ProvisionState: "enroll", 1158 TargetProvisionState: "", 1159 Maintenance: false, 1160 MaintenanceReason: "", 1161 Fault: "", 1162 LastError: "", 1163 Reservation: "", 1164 Driver: "ipmi", 1165 DriverInfo: map[string]any{}, 1166 DriverInternalInfo: map[string]any{}, 1167 Properties: map[string]any{}, 1168 InstanceInfo: map[string]any{}, 1169 InstanceUUID: "", 1170 ChassisUUID: "", 1171 Extra: map[string]any{}, 1172 ConsoleEnabled: false, 1173 RAIDConfig: map[string]any{}, 1174 TargetRAIDConfig: map[string]any{}, 1175 CleanStep: map[string]any{}, 1176 DeployStep: map[string]any{}, 1177 ResourceClass: "", 1178 BIOSInterface: "no-bios", 1179 BootInterface: "pxe", 1180 ConsoleInterface: "no-console", 1181 DeployInterface: "iscsi", 1182 FirmwareInterface: "no-firmware", 1183 InspectInterface: "no-inspect", 1184 ManagementInterface: "ipmitool", 1185 NetworkInterface: "flat", 1186 PowerInterface: "ipmitool", 1187 RAIDInterface: "no-raid", 1188 RescueInterface: "no-rescue", 1189 StorageInterface: "noop", 1190 Traits: []string{}, 1191 VendorInterface: "ipmitool", 1192 ConductorGroup: "", 1193 Protected: false, 1194 ProtectedReason: "", 1195 CreatedAt: createdAtBaz, 1196 UpdatedAt: updatedAt, 1197 Retired: false, 1198 RetiredReason: "No longer needed", 1199 DisablePowerOff: true, 1200 Links: []nodes.Link{ 1201 {Href: "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474", Rel: "self"}, 1202 {Href: "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474", Rel: "bookmark"}, 1203 }, 1204 Ports: []nodes.Link{ 1205 {Href: "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/ports", Rel: "self"}, 1206 {Href: "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/ports", Rel: "bookmark"}, 1207 }, 1208 PortGroups: []nodes.Link{ 1209 {Href: "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/portgroups", Rel: "self"}, 1210 {Href: "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/portgroups", Rel: "bookmark"}, 1211 }, 1212 States: []nodes.Link{ 1213 {Href: "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/states", Rel: "self"}, 1214 {Href: "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/states", Rel: "bookmark"}, 1215 }, 1216 Volume: []nodes.Link{ 1217 {Href: "http://ironic.example.com:6385/v1/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/volume", Rel: "self"}, 1218 {Href: "http://ironic.example.com:6385/nodes/c9afd385-5d89-4ecb-9e1c-68194da6b474/volume", Rel: "bookmark"}, 1219 }, 1220 } 1221 1222 ConfigDriveMap = nodes.ConfigDrive{ 1223 UserData: map[string]any{ 1224 "ignition": map[string]string{ 1225 "version": "2.2.0", 1226 }, 1227 "systemd": map[string]any{ 1228 "units": []map[string]any{{ 1229 "name": "example.service", 1230 "enabled": true, 1231 }, 1232 }, 1233 }, 1234 }, 1235 } 1236 1237 NodeBIOSSettings = []nodes.BIOSSetting{ 1238 { 1239 Name: "Proc1L2Cache", 1240 Value: "10x256 KB", 1241 }, 1242 { 1243 Name: "Proc1NumCores", 1244 Value: "10", 1245 }, 1246 { 1247 Name: "ProcVirtualization", 1248 Value: "Enabled", 1249 }, 1250 } 1251 1252 iTrue = true 1253 iFalse = false 1254 minLength = 0 1255 maxLength = 16 1256 lowerBound = 0 1257 upperBound = 20 1258 1259 NodeDetailBIOSSettings = []nodes.BIOSSetting{ 1260 { 1261 Name: "Proc1L2Cache", 1262 Value: "10x256 KB", 1263 AttributeType: "String", 1264 AllowableValues: []string{}, 1265 LowerBound: nil, 1266 UpperBound: nil, 1267 MinLength: &minLength, 1268 MaxLength: &maxLength, 1269 ReadOnly: &iTrue, 1270 ResetRequired: nil, 1271 Unique: nil, 1272 }, 1273 { 1274 Name: "Proc1NumCores", 1275 Value: "10", 1276 AttributeType: "Integer", 1277 AllowableValues: []string{}, 1278 LowerBound: &lowerBound, 1279 UpperBound: &upperBound, 1280 MinLength: nil, 1281 MaxLength: nil, 1282 ReadOnly: &iTrue, 1283 ResetRequired: nil, 1284 Unique: nil, 1285 }, 1286 { 1287 Name: "ProcVirtualization", 1288 Value: "Enabled", 1289 AttributeType: "Enumeration", 1290 AllowableValues: []string{"Enabled", "Disabled"}, 1291 LowerBound: nil, 1292 UpperBound: nil, 1293 MinLength: nil, 1294 MaxLength: nil, 1295 ReadOnly: &iFalse, 1296 ResetRequired: nil, 1297 Unique: nil, 1298 }, 1299 } 1300 1301 NodeSingleBIOSSetting = nodes.BIOSSetting{ 1302 Name: "ProcVirtualization", 1303 Value: "Enabled", 1304 } 1305 1306 NodeVendorPassthruMethods = nodes.VendorPassthruMethods{ 1307 CreateSubscription: nodes.CreateSubscriptionMethod{ 1308 HTTPMethods: []string{"POST"}, 1309 Async: false, 1310 Description: "", 1311 Attach: false, 1312 RequireExclusiveLock: true, 1313 }, 1314 DeleteSubscription: nodes.DeleteSubscriptionMethod{ 1315 HTTPMethods: []string{"DELETE"}, 1316 Async: false, 1317 Description: "", 1318 Attach: false, 1319 RequireExclusiveLock: true, 1320 }, 1321 GetSubscription: nodes.GetSubscriptionMethod{ 1322 HTTPMethods: []string{"GET"}, 1323 Async: false, 1324 Description: "", 1325 Attach: false, 1326 RequireExclusiveLock: true, 1327 }, 1328 GetAllSubscriptions: nodes.GetAllSubscriptionsMethod{ 1329 HTTPMethods: []string{"GET"}, 1330 Async: false, 1331 Description: "", 1332 Attach: false, 1333 RequireExclusiveLock: true, 1334 }, 1335 } 1336 1337 NodeGetAllSubscriptions = nodes.GetAllSubscriptionsVendorPassthru{ 1338 Context: "/redfish/v1/$metadata#EventDestinationCollection.EventDestinationCollection", 1339 Etag: "", 1340 Id: "/redfish/v1/EventService/Subscriptions", 1341 Type: "#EventDestinationCollection.EventDestinationCollection", 1342 Description: "List of Event subscriptions", 1343 Name: "Event Subscriptions Collection", 1344 Members: []map[string]string{{"@odata.id": "/redfish/v1/EventService/Subscriptions/62dbd1b6-f637-11eb-b551-4cd98f20754c"}}, 1345 MembersCount: 1, 1346 } 1347 1348 NodeGetSubscription = nodes.SubscriptionVendorPassthru{ 1349 Id: "62dbd1b6-f637-11eb-b551-4cd98f20754c", 1350 Context: "Ironic", 1351 Destination: "https://192.168.0.1/EventReceiver.php", 1352 EventTypes: []string{"Alert"}, 1353 Protocol: "Redfish", 1354 } 1355 1356 NodeCreateSubscriptionRequiredParameters = nodes.SubscriptionVendorPassthru{ 1357 Id: "344a3e2-978a-444e-990a-cbf47c62ef88", 1358 Context: "", 1359 Destination: "https://somedestinationurl", 1360 EventTypes: []string{"Alert"}, 1361 Protocol: "Redfish", 1362 } 1363 1364 NodeCreateSubscriptionAllParameters = nodes.SubscriptionVendorPassthru{ 1365 Id: "eaa43e2-018a-424e-990a-cbf47c62ef80", 1366 Context: "gophercloud", 1367 Destination: "https://someurl", 1368 EventTypes: []string{"Alert"}, 1369 Protocol: "Redfish", 1370 } 1371 1372 NodeInventoryData = nodes.InventoryData{ 1373 Inventory: inventorytest.Inventory, 1374 } 1375 1376 createdAtFirmware, _ = time.Parse(time.RFC3339, "2023-10-03T18:30:00+00:00") 1377 updatedAtFirmware, _ = time.Parse(time.RFC3339, "2023-10-03T18:45:54+00:00") 1378 lastVersion = "iLO 5 v2.81" 1379 NodeFirmwareList = []nodes.FirmwareComponent{ 1380 { 1381 CreatedAt: createdAtFirmware, 1382 UpdatedAt: nil, 1383 Component: "bios", 1384 InitialVersion: "U30 v2.36 (07/16/2020)", 1385 CurrentVersion: "U30 v2.36 (07/16/2020)", 1386 LastVersionFlashed: "", 1387 }, 1388 { 1389 CreatedAt: createdAtFirmware, 1390 UpdatedAt: &updatedAtFirmware, 1391 Component: "bmc", 1392 InitialVersion: "iLO 5 v2.78", 1393 CurrentVersion: "iLO 5 v2.81", 1394 LastVersionFlashed: lastVersion, 1395 }, 1396 } 1397 ) 1398 1399 // HandleNodeListSuccessfully sets up the test server to respond to a server List request. 1400 func HandleNodeListSuccessfully(t *testing.T) { 1401 th.Mux.HandleFunc("/nodes", func(w http.ResponseWriter, r *http.Request) { 1402 th.TestMethod(t, r, "GET") 1403 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1404 w.Header().Add("Content-Type", "application/json") 1405 if err := r.ParseForm(); err != nil { 1406 t.Errorf("Failed to parse request form %v", err) 1407 } 1408 1409 marker := r.Form.Get("marker") 1410 switch marker { 1411 case "": 1412 fmt.Fprint(w, NodeListBody) 1413 1414 case "9e5476bd-a4ec-4653-93d6-72c93aa682ba": 1415 fmt.Fprint(w, `{ "servers": [] }`) 1416 default: 1417 t.Fatalf("/nodes invoked with unexpected marker=[%s]", marker) 1418 } 1419 }) 1420 } 1421 1422 // HandleNodeListSuccessfully sets up the test server to respond to a server List request. 1423 func HandleNodeListDetailSuccessfully(t *testing.T) { 1424 th.Mux.HandleFunc("/nodes/detail", func(w http.ResponseWriter, r *http.Request) { 1425 th.TestMethod(t, r, "GET") 1426 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1427 w.Header().Add("Content-Type", "application/json") 1428 if err := r.ParseForm(); err != nil { 1429 t.Errorf("Failed to parse request form %v", err) 1430 } 1431 1432 fmt.Fprint(w, NodeListDetailBody) 1433 }) 1434 } 1435 1436 // HandleServerCreationSuccessfully sets up the test server to respond to a server creation request 1437 // with a given response. 1438 func HandleNodeCreationSuccessfully(t *testing.T, response string) { 1439 th.Mux.HandleFunc("/nodes", func(w http.ResponseWriter, r *http.Request) { 1440 th.TestMethod(t, r, "POST") 1441 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1442 th.TestJSONRequest(t, r, `{ 1443 "boot_interface": "pxe", 1444 "driver": "ipmi", 1445 "driver_info": { 1446 "deploy_kernel": "http://172.22.0.1/images/tinyipa-stable-rocky.vmlinuz", 1447 "deploy_ramdisk": "http://172.22.0.1/images/tinyipa-stable-rocky.gz", 1448 "ipmi_address": "192.168.122.1", 1449 "ipmi_password": "admin", 1450 "ipmi_port": "6230", 1451 "ipmi_username": "admin" 1452 }, 1453 "firmware_interface": "no-firmware", 1454 "name": "foo" 1455 }`) 1456 1457 w.WriteHeader(http.StatusAccepted) 1458 w.Header().Add("Content-Type", "application/json") 1459 fmt.Fprint(w, response) 1460 }) 1461 } 1462 1463 // HandleNodeDeletionSuccessfully sets up the test server to respond to a server deletion request. 1464 func HandleNodeDeletionSuccessfully(t *testing.T) { 1465 th.Mux.HandleFunc("/nodes/asdfasdfasdf", func(w http.ResponseWriter, r *http.Request) { 1466 th.TestMethod(t, r, "DELETE") 1467 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1468 1469 w.WriteHeader(http.StatusNoContent) 1470 }) 1471 } 1472 1473 func HandleNodeGetSuccessfully(t *testing.T) { 1474 th.Mux.HandleFunc("/nodes/1234asdf", func(w http.ResponseWriter, r *http.Request) { 1475 th.TestMethod(t, r, "GET") 1476 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1477 th.TestHeader(t, r, "Accept", "application/json") 1478 1479 fmt.Fprint(w, SingleNodeBody) 1480 }) 1481 } 1482 1483 func HandleNodeUpdateSuccessfully(t *testing.T, response string) { 1484 th.Mux.HandleFunc("/nodes/1234asdf", func(w http.ResponseWriter, r *http.Request) { 1485 th.TestMethod(t, r, "PATCH") 1486 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1487 th.TestHeader(t, r, "Accept", "application/json") 1488 th.TestHeader(t, r, "Content-Type", "application/json") 1489 th.TestJSONRequest(t, r, `[{"op": "replace", "path": "/properties", "value": {"root_gb": 25}}]`) 1490 1491 fmt.Fprint(w, response) 1492 }) 1493 } 1494 1495 func HandleNodeValidateSuccessfully(t *testing.T) { 1496 th.Mux.HandleFunc("/nodes/1234asdf/validate", func(w http.ResponseWriter, r *http.Request) { 1497 th.TestMethod(t, r, "GET") 1498 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1499 th.TestHeader(t, r, "Accept", "application/json") 1500 1501 fmt.Fprint(w, NodeValidationBody) 1502 }) 1503 } 1504 1505 // HandleInjectNMISuccessfully sets up the test server to respond to a node InjectNMI request 1506 func HandleInjectNMISuccessfully(t *testing.T) { 1507 th.Mux.HandleFunc("/nodes/1234asdf/management/inject_nmi", func(w http.ResponseWriter, r *http.Request) { 1508 th.TestMethod(t, r, "PUT") 1509 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1510 th.TestJSONRequest(t, r, "{}") 1511 1512 w.WriteHeader(http.StatusNoContent) 1513 }) 1514 } 1515 1516 // HandleSetBootDeviceSuccessfully sets up the test server to respond to a set boot device request for a node 1517 func HandleSetBootDeviceSuccessfully(t *testing.T) { 1518 th.Mux.HandleFunc("/nodes/1234asdf/management/boot_device", func(w http.ResponseWriter, r *http.Request) { 1519 th.TestMethod(t, r, "PUT") 1520 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1521 th.TestJSONRequest(t, r, NodeBootDeviceBody) 1522 1523 w.WriteHeader(http.StatusNoContent) 1524 }) 1525 } 1526 1527 // HandleGetBootDeviceSuccessfully sets up the test server to respond to a get boot device request for a node 1528 func HandleGetBootDeviceSuccessfully(t *testing.T) { 1529 th.Mux.HandleFunc("/nodes/1234asdf/management/boot_device", func(w http.ResponseWriter, r *http.Request) { 1530 th.TestMethod(t, r, "GET") 1531 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1532 w.WriteHeader(http.StatusOK) 1533 fmt.Fprint(w, NodeBootDeviceBody) 1534 }) 1535 } 1536 1537 // HandleGetBootDeviceSuccessfully sets up the test server to respond to a get boot device request for a node 1538 func HandleGetSupportedBootDeviceSuccessfully(t *testing.T) { 1539 th.Mux.HandleFunc("/nodes/1234asdf/management/boot_device/supported", func(w http.ResponseWriter, r *http.Request) { 1540 th.TestMethod(t, r, "GET") 1541 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1542 w.WriteHeader(http.StatusOK) 1543 fmt.Fprint(w, NodeSupportedBootDeviceBody) 1544 }) 1545 } 1546 1547 func HandleNodeChangeProvisionStateActive(t *testing.T) { 1548 th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { 1549 th.TestMethod(t, r, "PUT") 1550 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1551 th.TestJSONRequest(t, r, NodeProvisionStateActiveBody) 1552 w.WriteHeader(http.StatusAccepted) 1553 }) 1554 } 1555 1556 func HandleNodeChangeProvisionStateActiveWithSteps(t *testing.T) { 1557 th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { 1558 th.TestMethod(t, r, "PUT") 1559 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1560 th.TestJSONRequest(t, r, NodeProvisionStateActiveBodyWithSteps) 1561 w.WriteHeader(http.StatusAccepted) 1562 }) 1563 } 1564 1565 func HandleNodeChangeProvisionStateClean(t *testing.T) { 1566 th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { 1567 th.TestMethod(t, r, "PUT") 1568 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1569 th.TestJSONRequest(t, r, NodeProvisionStateCleanBody) 1570 w.WriteHeader(http.StatusAccepted) 1571 }) 1572 } 1573 1574 func HandleNodeChangeProvisionStateCleanWithConflict(t *testing.T) { 1575 th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { 1576 th.TestMethod(t, r, "PUT") 1577 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1578 th.TestJSONRequest(t, r, NodeProvisionStateCleanBody) 1579 w.WriteHeader(http.StatusConflict) 1580 }) 1581 } 1582 1583 func HandleNodeChangeProvisionStateConfigDrive(t *testing.T) { 1584 th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { 1585 th.TestMethod(t, r, "PUT") 1586 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1587 th.TestJSONRequest(t, r, NodeProvisionStateConfigDriveBody) 1588 w.WriteHeader(http.StatusAccepted) 1589 }) 1590 } 1591 1592 func HandleNodeChangeProvisionStateService(t *testing.T) { 1593 th.Mux.HandleFunc("/nodes/1234asdf/states/provision", func(w http.ResponseWriter, r *http.Request) { 1594 th.TestMethod(t, r, "PUT") 1595 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1596 th.TestJSONRequest(t, r, NodeProvisionStateServiceBody) 1597 w.WriteHeader(http.StatusAccepted) 1598 }) 1599 } 1600 1601 // HandleChangePowerStateSuccessfully sets up the test server to respond to a change power state request for a node 1602 func HandleChangePowerStateSuccessfully(t *testing.T) { 1603 th.Mux.HandleFunc("/nodes/1234asdf/states/power", func(w http.ResponseWriter, r *http.Request) { 1604 th.TestMethod(t, r, "PUT") 1605 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1606 th.TestJSONRequest(t, r, `{ 1607 "target": "power on", 1608 "timeout": 100 1609 }`) 1610 1611 w.WriteHeader(http.StatusAccepted) 1612 }) 1613 } 1614 1615 // HandleChangePowerStateWithConflict sets up the test server to respond to a change power state request for a node with a 409 error 1616 func HandleChangePowerStateWithConflict(t *testing.T) { 1617 th.Mux.HandleFunc("/nodes/1234asdf/states/power", func(w http.ResponseWriter, r *http.Request) { 1618 th.TestMethod(t, r, "PUT") 1619 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1620 th.TestJSONRequest(t, r, `{ 1621 "target": "power on", 1622 "timeout": 100 1623 }`) 1624 1625 w.WriteHeader(http.StatusConflict) 1626 }) 1627 } 1628 1629 func HandleSetRAIDConfig(t *testing.T) { 1630 th.Mux.HandleFunc("/nodes/1234asdf/states/raid", func(w http.ResponseWriter, r *http.Request) { 1631 th.TestMethod(t, r, "PUT") 1632 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1633 th.TestJSONRequest(t, r, ` 1634 { 1635 "logical_disks" : [ 1636 { 1637 "size_gb" : 100, 1638 "is_root_volume" : true, 1639 "raid_level" : "1" 1640 } 1641 ] 1642 } 1643 `) 1644 1645 w.WriteHeader(http.StatusNoContent) 1646 }) 1647 } 1648 1649 func HandleSetRAIDConfigMaxSize(t *testing.T) { 1650 th.Mux.HandleFunc("/nodes/1234asdf/states/raid", func(w http.ResponseWriter, r *http.Request) { 1651 th.TestMethod(t, r, "PUT") 1652 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1653 th.TestJSONRequest(t, r, ` 1654 { 1655 "logical_disks" : [ 1656 { 1657 "size_gb" : "MAX", 1658 "is_root_volume" : true, 1659 "raid_level" : "1" 1660 } 1661 ] 1662 } 1663 `) 1664 1665 w.WriteHeader(http.StatusNoContent) 1666 }) 1667 } 1668 1669 func HandleListBIOSSettingsSuccessfully(t *testing.T) { 1670 th.Mux.HandleFunc("/nodes/1234asdf/bios", func(w http.ResponseWriter, r *http.Request) { 1671 th.TestMethod(t, r, "GET") 1672 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1673 th.TestHeader(t, r, "Accept", "application/json") 1674 1675 fmt.Fprint(w, NodeBIOSSettingsBody) 1676 }) 1677 } 1678 1679 func HandleListDetailBIOSSettingsSuccessfully(t *testing.T) { 1680 th.Mux.HandleFunc("/nodes/1234asdf/bios", func(w http.ResponseWriter, r *http.Request) { 1681 th.TestMethod(t, r, "GET") 1682 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1683 th.TestHeader(t, r, "Accept", "application/json") 1684 1685 fmt.Fprint(w, NodeDetailBIOSSettingsBody) 1686 }) 1687 } 1688 1689 func HandleGetBIOSSettingSuccessfully(t *testing.T) { 1690 th.Mux.HandleFunc("/nodes/1234asdf/bios/ProcVirtualization", func(w http.ResponseWriter, r *http.Request) { 1691 th.TestMethod(t, r, "GET") 1692 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1693 th.TestHeader(t, r, "Accept", "application/json") 1694 1695 fmt.Fprint(w, NodeSingleBIOSSettingBody) 1696 }) 1697 } 1698 1699 func HandleGetVendorPassthruMethodsSuccessfully(t *testing.T) { 1700 th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru/methods", func(w http.ResponseWriter, r *http.Request) { 1701 th.TestMethod(t, r, "GET") 1702 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1703 th.TestHeader(t, r, "Accept", "application/json") 1704 1705 fmt.Fprint(w, NodeVendorPassthruMethodsBody) 1706 }) 1707 } 1708 1709 func HandleGetAllSubscriptionsVendorPassthruSuccessfully(t *testing.T) { 1710 th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { 1711 th.TestMethod(t, r, "GET") 1712 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1713 th.TestHeader(t, r, "Accept", "application/json") 1714 th.TestFormValues(t, r, map[string]string{"method": "get_all_subscriptions"}) 1715 1716 fmt.Fprint(w, NodeGetAllSubscriptionsVnedorPassthruBody) 1717 }) 1718 } 1719 1720 func HandleGetSubscriptionVendorPassthruSuccessfully(t *testing.T) { 1721 th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { 1722 th.TestMethod(t, r, "GET") 1723 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1724 th.TestHeader(t, r, "Accept", "application/json") 1725 th.TestFormValues(t, r, map[string]string{"method": "get_subscription"}) 1726 th.TestJSONRequest(t, r, ` 1727 { 1728 "id" : "62dbd1b6-f637-11eb-b551-4cd98f20754c" 1729 } 1730 `) 1731 1732 fmt.Fprint(w, NodeGetSubscriptionVendorPassthruBody) 1733 }) 1734 } 1735 1736 func HandleCreateSubscriptionVendorPassthruAllParametersSuccessfully(t *testing.T) { 1737 th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { 1738 th.TestMethod(t, r, "POST") 1739 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1740 th.TestHeader(t, r, "Accept", "application/json") 1741 th.TestFormValues(t, r, map[string]string{"method": "create_subscription"}) 1742 th.TestJSONRequest(t, r, ` 1743 { 1744 "Context": "gophercloud", 1745 "EventTypes": ["Alert"], 1746 "HttpHeaders": [{"Content-Type":"application/json"}], 1747 "Protocol": "Redfish", 1748 "Destination" : "https://someurl" 1749 } 1750 `) 1751 1752 fmt.Fprint(w, NodeCreateSubscriptionVendorPassthruAllParametersBody) 1753 }) 1754 } 1755 1756 func HandleCreateSubscriptionVendorPassthruRequiredParametersSuccessfully(t *testing.T) { 1757 th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { 1758 th.TestMethod(t, r, "POST") 1759 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1760 th.TestHeader(t, r, "Accept", "application/json") 1761 th.TestFormValues(t, r, map[string]string{"method": "create_subscription"}) 1762 th.TestJSONRequest(t, r, ` 1763 { 1764 "Destination" : "https://somedestinationurl" 1765 } 1766 `) 1767 1768 fmt.Fprint(w, NodeCreateSubscriptionVendorPassthruRequiredParametersBody) 1769 }) 1770 } 1771 1772 func HandleDeleteSubscriptionVendorPassthruSuccessfully(t *testing.T) { 1773 th.Mux.HandleFunc("/nodes/1234asdf/vendor_passthru", func(w http.ResponseWriter, r *http.Request) { 1774 th.TestMethod(t, r, "DELETE") 1775 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1776 th.TestHeader(t, r, "Accept", "application/json") 1777 th.TestFormValues(t, r, map[string]string{"method": "delete_subscription"}) 1778 th.TestJSONRequest(t, r, ` 1779 { 1780 "id" : "344a3e2-978a-444e-990a-cbf47c62ef88" 1781 } 1782 `) 1783 1784 w.WriteHeader(http.StatusNoContent) 1785 }) 1786 } 1787 1788 func HandleSetNodeMaintenanceSuccessfully(t *testing.T) { 1789 th.Mux.HandleFunc("/nodes/1234asdf/maintenance", func(w http.ResponseWriter, r *http.Request) { 1790 th.TestMethod(t, r, "PUT") 1791 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1792 th.TestJSONRequest(t, r, NodeSetMaintenanceBody) 1793 1794 w.WriteHeader(http.StatusAccepted) 1795 }) 1796 } 1797 1798 func HandleUnsetNodeMaintenanceSuccessfully(t *testing.T) { 1799 th.Mux.HandleFunc("/nodes/1234asdf/maintenance", func(w http.ResponseWriter, r *http.Request) { 1800 th.TestMethod(t, r, "DELETE") 1801 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1802 1803 w.WriteHeader(http.StatusAccepted) 1804 }) 1805 } 1806 1807 // HandleGetInventorySuccessfully sets up the test server to respond to a get inventory request for a node 1808 func HandleGetInventorySuccessfully(t *testing.T) { 1809 th.Mux.HandleFunc("/nodes/1234asdf/inventory", func(w http.ResponseWriter, r *http.Request) { 1810 th.TestMethod(t, r, "GET") 1811 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1812 w.WriteHeader(http.StatusOK) 1813 fmt.Fprint(w, NodeInventoryBody) 1814 }) 1815 } 1816 1817 // HandleListFirmware 1818 func HandleListFirmwareSuccessfully(t *testing.T) { 1819 th.Mux.HandleFunc("/nodes/1234asdf/firmware", func(w http.ResponseWriter, r *http.Request) { 1820 th.TestMethod(t, r, "GET") 1821 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1822 w.WriteHeader(http.StatusOK) 1823 fmt.Fprint(w, NodeFirmwareListBody) 1824 }) 1825 } 1826 1827 func HandleAttachVirtualMediaSuccessfully(t *testing.T, withSource bool) { 1828 th.Mux.HandleFunc("/nodes/1234asdf/vmedia", func(w http.ResponseWriter, r *http.Request) { 1829 th.TestMethod(t, r, "POST") 1830 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1831 if withSource { 1832 th.TestJSONRequest(t, r, NodeVirtualMediaAttachBodyWithSource) 1833 } else { 1834 th.TestJSONRequest(t, r, NodeVirtualMediaAttachBody) 1835 } 1836 w.WriteHeader(http.StatusNoContent) 1837 }) 1838 } 1839 1840 func HandleDetachVirtualMediaSuccessfully(t *testing.T, withType bool) { 1841 th.Mux.HandleFunc("/nodes/1234asdf/vmedia", func(w http.ResponseWriter, r *http.Request) { 1842 th.TestMethod(t, r, "DELETE") 1843 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 1844 if withType { 1845 th.TestFormValues(t, r, map[string]string{"device_types": "cdrom"}) 1846 } else { 1847 th.TestFormValues(t, r, map[string]string{}) 1848 } 1849 w.WriteHeader(http.StatusNoContent) 1850 }) 1851 }