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