github.com/openshift/installer@v1.4.17/pkg/asset/agent/agentconfig/agenthosts_test.go (about) 1 package agentconfig 2 3 import ( 4 "context" 5 "net" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 "k8s.io/utils/pointer" 12 13 aiv1beta1 "github.com/openshift/assisted-service/api/v1beta1" 14 "github.com/openshift/installer/pkg/asset" 15 agentAsset "github.com/openshift/installer/pkg/asset/agent" 16 "github.com/openshift/installer/pkg/asset/agent/joiner" 17 "github.com/openshift/installer/pkg/asset/agent/workflow" 18 "github.com/openshift/installer/pkg/asset/installconfig" 19 "github.com/openshift/installer/pkg/ipnet" 20 "github.com/openshift/installer/pkg/types" 21 "github.com/openshift/installer/pkg/types/agent" 22 "github.com/openshift/installer/pkg/types/baremetal" 23 ) 24 25 const ( 26 agentNetworkConfigOne = `interfaces: 27 - ipv4: 28 address: 29 - ip: 192.168.111.80 30 prefix-length: 24 31 dhcp: false 32 enabled: true 33 mac-address: 28:d2:44:d2:b2:1a 34 name: eth0 35 state: up 36 type: ethernet 37 ` 38 agentNetworkConfigTwo = `interfaces: 39 - ipv4: 40 address: 41 - ip: 192.168.111.81 42 prefix-length: 24 43 dhcp: false 44 enabled: true 45 mac-address: 28:d2:44:d2:b2:1b 46 name: eth0 47 state: up 48 type: ethernet 49 ` 50 installNetworkConfigOne = `interfaces: 51 - ipv4: 52 address: 53 - ip: 192.168.111.80 54 prefix-length: 24 55 dhcp: false 56 enabled: true 57 mac-address: 28:d2:44:b0:bf:01 58 name: eth0 59 state: up 60 type: ethernet 61 ` 62 installNetworkConfigTwo = `interfaces: 63 - ipv4: 64 address: 65 - ip: 192.168.111.81 66 prefix-length: 24 67 dhcp: false 68 enabled: true 69 mac-address: 28:d2:44:b0:bf:02 70 name: eth0 71 state: up 72 type: ethernet 73 ` 74 ) 75 76 func TestAgentHosts_Generate(t *testing.T) { 77 cases := []struct { 78 name string 79 dependencies []asset.Asset 80 expectedError string 81 expectedConfig *AgentHostsBuilder 82 }{ 83 { 84 name: "host-from-add-nodes-config", 85 dependencies: []asset.Asset{ 86 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeAddNodes}, 87 &joiner.AddNodesConfig{ 88 Config: joiner.Config{ 89 Hosts: []agent.Host{ 90 { 91 Hostname: "extra-worker-0", 92 Role: "worker", 93 Interfaces: []*aiv1beta1.Interface{ 94 { 95 Name: "enp3s1", 96 MacAddress: "28:d2:44:d2:b2:1a", 97 }, 98 }, 99 }, 100 }, 101 }, 102 }, 103 getNoHostsInstallConfig(), 104 getNoHostsAgentConfig(), 105 }, 106 expectedConfig: agentHosts().hosts(agentHost().name("extra-worker-0").role("worker").interfaces(iface("enp3s1", "28:d2:44:d2:b2:1a"))), 107 }, 108 { 109 name: "no-hosts", 110 dependencies: []asset.Asset{ 111 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 112 &joiner.AddNodesConfig{}, 113 getNoHostsInstallConfig(), 114 getNoHostsAgentConfig(), 115 }, 116 expectedConfig: nil, 117 }, 118 { 119 name: "host-from-agent-config", 120 dependencies: []asset.Asset{ 121 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 122 &joiner.AddNodesConfig{}, 123 getInstallConfigSingleHost(), 124 getAgentConfigSingleHost(), 125 }, 126 expectedConfig: agentHosts().hosts(agentHost().name("test").role("master").interfaces(iface("enp3s1", "28:d2:44:d2:b2:1a")).deviceHint()), 127 }, 128 { 129 name: "host-from-install-config", 130 dependencies: []asset.Asset{ 131 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 132 &joiner.AddNodesConfig{}, 133 getInstallConfigSingleHost(), 134 getNoHostsAgentConfig(), 135 }, 136 expectedConfig: agentHosts().hosts(agentHost().name("test").role("master").interfaces(iface("boot", "28:d2:44:b0:bf:01")).deviceHint()), 137 }, 138 { 139 name: "multi-host-from-agent-config", 140 dependencies: []asset.Asset{ 141 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 142 &joiner.AddNodesConfig{}, 143 getInstallConfigSingleHost(), 144 getAgentConfigMultiHost(), 145 }, 146 expectedConfig: agentHosts().hosts( 147 agentHost().name("test").role("master").interfaces(iface("enp3s1", "28:d2:44:d2:b2:1a")).deviceHint().networkConfig(agentNetworkConfigOne), 148 agentHost().name("test-2").role("worker").interfaces(iface("enp3s1", "28:d2:44:d2:b2:1b")).networkConfig(agentNetworkConfigTwo)), 149 }, 150 { 151 name: "multi-host-from-install-config", 152 dependencies: []asset.Asset{ 153 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 154 &joiner.AddNodesConfig{}, 155 getInstallConfigMultiHost(), 156 getNoHostsAgentConfig(), 157 }, 158 expectedConfig: agentHosts().hosts( 159 agentHost().name("test").role("master").interfaces(iface("eth0", "28:d2:44:b0:bf:01")).deviceHint().networkConfig(installNetworkConfigOne), 160 agentHost().name("test-2").role("worker").interfaces(iface("eth0", "28:d2:44:b0:bf:02")).networkConfig(installNetworkConfigTwo)), 161 }, 162 { 163 name: "unsupported-device-name-agent-config", 164 dependencies: []asset.Asset{ 165 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 166 &joiner.AddNodesConfig{}, 167 getInstallConfigSingleHost(), 168 getAgentConfigUnsupportedDeviceName(), 169 }, 170 expectedError: "invalid Hosts configuration: Hosts[0].rootDeviceHints.deviceName: Invalid value: \"/dev/disk/by-id/wwn-0x600508e000000000ce506dc50ab0ad05\": Device Name of root device hint must be path in /dev/ or /dev/disk/by-path/", 171 expectedConfig: nil, 172 }, 173 { 174 name: "unsupported-wwn-extension-install-config", 175 dependencies: []asset.Asset{ 176 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 177 &joiner.AddNodesConfig{}, 178 getInstallConfigUnsupportedWWNExtension(), 179 getNoHostsAgentConfig(), 180 }, 181 expectedError: "invalid Hosts configuration: Hosts[0].rootDeviceHints.wwnWithExtension: Forbidden: WWN extensions are not supported in root device hints", 182 expectedConfig: nil, 183 }, 184 { 185 name: "unsupported-www-vendor-extension-agent-config", 186 dependencies: []asset.Asset{ 187 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 188 &joiner.AddNodesConfig{}, 189 getInstallConfigSingleHost(), 190 getAgentConfigUnsupportedWWNVendorExtension(), 191 }, 192 expectedError: "invalid Hosts configuration: Hosts[0].rootDeviceHints.wwnVendorExtension: Forbidden: WWN vendor extensions are not supported in root device hints", 193 expectedConfig: nil, 194 }, 195 { 196 name: "node-hostname-and-role-are-not-required", 197 dependencies: []asset.Asset{ 198 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 199 &joiner.AddNodesConfig{}, 200 getInstallConfigNoHostnameOrRole(), 201 getNoHostsAgentConfig(), 202 }, 203 expectedConfig: agentHosts().hosts(agentHost().interfaces(iface("boot", "28:d2:44:b0:bf:01")).deviceHint()), 204 }, 205 { 206 name: "host-roles-have-incorrect-values", 207 dependencies: []asset.Asset{ 208 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 209 &joiner.AddNodesConfig{}, 210 getInstallConfigSingleHost(), 211 getAgentConfigInvalidHostRole(), 212 }, 213 expectedError: "invalid Hosts configuration: Hosts[0].Host: Forbidden: host role has incorrect value. Role must either be 'master' or 'worker'", 214 expectedConfig: nil, 215 }, 216 { 217 name: "different-hosts-cannot-have-same-mac", 218 dependencies: []asset.Asset{ 219 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 220 &joiner.AddNodesConfig{}, 221 getInstallConfigSameMac(), 222 getNoHostsAgentConfig(), 223 }, 224 expectedError: "invalid Hosts configuration: Hosts[1].Interfaces[0].macAddress: Invalid value: \"28:d2:44:b0:bf:01\": duplicate MAC address found", 225 expectedConfig: nil, 226 }, 227 { 228 name: "invalid-mac", 229 dependencies: []asset.Asset{ 230 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 231 &joiner.AddNodesConfig{}, 232 getInstallConfigSingleHost(), 233 getAgentConfigInvalidMac(), 234 }, 235 expectedError: "invalid Hosts configuration: Hosts[0].Interfaces[0].macAddress: Invalid value: \"000000\": address 000000: invalid MAC address", 236 expectedConfig: nil, 237 }, 238 { 239 name: "duplicate-mac-same-host-agent-config", 240 dependencies: []asset.Asset{ 241 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 242 &joiner.AddNodesConfig{}, 243 getInstallConfigSingleHost(), 244 getAgentConfigInvalidInterfaces(), 245 }, 246 expectedError: "invalid Hosts configuration: Hosts[0].Interfaces[1].macAddress: Invalid value: \"28:d2:44:d2:b2:1a\": duplicate MAC address found", 247 expectedConfig: nil, 248 }, 249 { 250 name: "duplicate-mac-same-host-install-config", 251 dependencies: []asset.Asset{ 252 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 253 &joiner.AddNodesConfig{}, 254 getInstallConfigInvalidInterfaces(), 255 getNoHostsAgentConfig(), 256 }, 257 expectedError: "invalid Hosts configuration: Hosts[0].Interfaces[1].macAddress: Invalid value: \"28:d2:44:b0:bf:01\": duplicate MAC address found", 258 expectedConfig: nil, 259 }, 260 { 261 name: "invalid-rendezvous-agent-config", 262 dependencies: []asset.Asset{ 263 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 264 &joiner.AddNodesConfig{}, 265 getInstallConfigSingleHost(), 266 getAgentConfigInvalidRendezvousIP(), 267 }, 268 expectedError: "invalid Hosts configuration: Hosts[1].Host: Forbidden: Host test-2 has role 'worker' and has the rendezvousIP assigned to it. The rendezvousIP must be assigned to a control plane host.", 269 expectedConfig: nil, 270 }, 271 { 272 name: "invalid-rendezvous-install-config", 273 dependencies: []asset.Asset{ 274 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 275 &joiner.AddNodesConfig{}, 276 getInstallConfigInvalidRendezvousIP(), 277 getNoHostsAgentConfig(), 278 }, 279 expectedError: "invalid Hosts configuration: Hosts[0].Host: Forbidden: Host test has role 'worker' and has the rendezvousIP assigned to it. The rendezvousIP must be assigned to a control plane host.", 280 expectedConfig: nil, 281 }, 282 { 283 name: "host-missing-interface-error", 284 dependencies: []asset.Asset{ 285 &workflow.AgentWorkflow{Workflow: workflow.AgentWorkflowTypeInstall}, 286 &joiner.AddNodesConfig{}, 287 getInstallConfigSingleHost(), 288 getAgentConfigMissingInterfaces(), 289 }, 290 expectedError: "invalid Hosts configuration: [Hosts[0].Interfaces: Required value: at least one interface must be defined for each node, Hosts[1].Interfaces: Required value: at least one interface must be defined for each node, Hosts[2].Interfaces: Required value: at least one interface must be defined for each node]", 291 expectedConfig: nil, 292 }, 293 } 294 for _, tc := range cases { 295 t.Run(tc.name, func(t *testing.T) { 296 parents := asset.Parents{} 297 parents.Add(tc.dependencies...) 298 299 asset := &AgentHosts{} 300 err := asset.Generate(context.Background(), parents) 301 302 if tc.expectedError != "" { 303 assert.Equal(t, tc.expectedError, err.Error()) 304 } else { 305 assert.NoError(t, err) 306 if tc.expectedConfig != nil { 307 assert.Equal(t, tc.expectedConfig.build().Hosts, asset.Hosts, "unexpected Config in AgentHosts") 308 } else { 309 assert.Nil(t, asset.Hosts) 310 } 311 } 312 }) 313 } 314 } 315 316 func getNoHostsInstallConfig() *agentAsset.OptionalInstallConfig { 317 _, newCidr, err1 := net.ParseCIDR("192.168.111.0/24") 318 _, machineNetCidr, err2 := net.ParseCIDR("10.10.11.0/24") 319 if err1 != nil || err2 != nil { 320 return nil 321 } 322 323 return &agentAsset.OptionalInstallConfig{ 324 AssetBase: installconfig.AssetBase{ 325 Config: &types.InstallConfig{ 326 ObjectMeta: metav1.ObjectMeta{ 327 Name: "test-cluster", 328 }, 329 BaseDomain: "test-domain", 330 PullSecret: "{\"auths\":{\"example.com\":{\"auth\":\"authorization value\"}}}", 331 ControlPlane: &types.MachinePool{ 332 Name: "master", 333 Replicas: pointer.Int64(3), 334 Platform: types.MachinePoolPlatform{}, 335 }, 336 Networking: &types.Networking{ 337 MachineNetwork: []types.MachineNetworkEntry{ 338 { 339 CIDR: ipnet.IPNet{IPNet: *machineNetCidr}, 340 }, 341 }, 342 ClusterNetwork: []types.ClusterNetworkEntry{ 343 { 344 CIDR: ipnet.IPNet{IPNet: *newCidr}, 345 HostPrefix: 23, 346 }, 347 }, 348 ServiceNetwork: []ipnet.IPNet{ 349 *ipnet.MustParseCIDR("172.30.0.0/16"), 350 }, 351 }, 352 Platform: types.Platform{ 353 BareMetal: &baremetal.Platform{ 354 APIVIPs: []string{"192.168.122.10"}, 355 IngressVIPs: []string{"192.168.122.11"}, 356 }, 357 }, 358 }, 359 }, 360 Supplied: true, 361 } 362 } 363 364 func getNoHostsAgentConfig() *AgentConfig { 365 return &AgentConfig{ 366 Config: &agent.Config{ 367 TypeMeta: metav1.TypeMeta{ 368 Kind: "AgentConfig", 369 APIVersion: "v1alpha1", 370 }, 371 ObjectMeta: metav1.ObjectMeta{ 372 Name: "ocp-edge-cluster-0", 373 Namespace: "cluster-0", 374 }, 375 RendezvousIP: "192.168.111.80", 376 }, 377 } 378 } 379 380 func getAgentConfigSingleHost() *AgentConfig { 381 a := getNoHostsAgentConfig() 382 a.Config.Hosts = []agent.Host{ 383 { 384 Hostname: "test", 385 Role: "master", 386 Interfaces: []*aiv1beta1.Interface{ 387 { 388 Name: "enp3s1", 389 MacAddress: "28:d2:44:d2:b2:1a", 390 }, 391 }, 392 RootDeviceHints: baremetal.RootDeviceHints{ 393 DeviceName: "/dev/sda", 394 }, 395 }, 396 } 397 return a 398 } 399 400 func getAgentConfigMultiHost() *AgentConfig { 401 a := getAgentConfigSingleHost() 402 a.Config.Hosts[0].NetworkConfig.Raw = []byte(agentNetworkConfigOne) 403 host := agent.Host{ 404 Hostname: "test-2", 405 Role: "worker", 406 Interfaces: []*aiv1beta1.Interface{ 407 { 408 Name: "enp3s1", 409 MacAddress: "28:d2:44:d2:b2:1b", 410 }, 411 }, 412 NetworkConfig: aiv1beta1.NetConfig{ 413 Raw: []byte(agentNetworkConfigTwo), 414 }, 415 } 416 a.Config.Hosts = append(a.Config.Hosts, host) 417 return a 418 } 419 420 func getAgentConfigUnsupportedDeviceName() *AgentConfig { 421 a := getAgentConfigSingleHost() 422 a.Config.Hosts[0].RootDeviceHints = baremetal.RootDeviceHints{ 423 DeviceName: "/dev/disk/by-id/wwn-0x600508e000000000ce506dc50ab0ad05", 424 } 425 return a 426 } 427 428 func getAgentConfigUnsupportedWWNVendorExtension() *AgentConfig { 429 a := getAgentConfigSingleHost() 430 a.Config.Hosts[0].RootDeviceHints = baremetal.RootDeviceHints{ 431 WWNVendorExtension: "wwn-with-vendor-extension-value", 432 } 433 return a 434 } 435 436 func getAgentConfigInvalidHostRole() *AgentConfig { 437 a := getAgentConfigSingleHost() 438 a.Config.Hosts[0].Role = "invalid-role" 439 return a 440 } 441 442 func getAgentConfigInvalidMac() *AgentConfig { 443 a := getAgentConfigSingleHost() 444 a.Config.Hosts[0].Interfaces[0].MacAddress = "000000" 445 return a 446 } 447 448 func getAgentConfigInvalidInterfaces() *AgentConfig { 449 a := getNoHostsAgentConfig() 450 a.Config.Hosts = []agent.Host{ 451 { 452 Hostname: "test", 453 Role: "master", 454 Interfaces: []*aiv1beta1.Interface{ 455 { 456 Name: "enp3s1", 457 MacAddress: "28:d2:44:d2:b2:1a", 458 }, 459 { 460 Name: "enp3s2", 461 MacAddress: "28:d2:44:d2:b2:1a", 462 }, 463 }, 464 }, 465 } 466 return a 467 } 468 469 func getAgentConfigMissingInterfaces() *AgentConfig { 470 a := getNoHostsAgentConfig() 471 a.Config.Hosts = []agent.Host{ 472 { 473 Hostname: "control-0.example.org", 474 Role: "master", 475 }, 476 { 477 Hostname: "control-1.example.org", 478 Role: "master", 479 }, 480 { 481 Hostname: "control-2.example.org", 482 Role: "master", 483 }, 484 } 485 return a 486 } 487 488 func getAgentConfigInvalidRendezvousIP() *AgentConfig { 489 a := getAgentConfigMultiHost() 490 a.Config.RendezvousIP = "192.168.111.81" 491 return a 492 } 493 494 func getInstallConfigSingleHost() *agentAsset.OptionalInstallConfig { 495 a := getNoHostsInstallConfig() 496 a.Config.Platform.BareMetal.Hosts = []*baremetal.Host{ 497 { 498 Name: "test", 499 Role: "master", 500 BootMACAddress: "28:d2:44:b0:bf:01", 501 RootDeviceHints: &baremetal.RootDeviceHints{ 502 DeviceName: "/dev/sda", 503 }, 504 }, 505 } 506 return a 507 } 508 509 func getInstallConfigMultiHost() *agentAsset.OptionalInstallConfig { 510 a := getInstallConfigSingleHost() 511 a.Config.Platform.BareMetal.Hosts[0].NetworkConfig = &apiextv1.JSON{ 512 Raw: []byte(installNetworkConfigOne), 513 } 514 host := &baremetal.Host{ 515 Name: "test-2", 516 Role: "worker", 517 BootMACAddress: "28:d2:44:b0:bf:02", 518 NetworkConfig: &apiextv1.JSON{ 519 Raw: []byte(installNetworkConfigTwo), 520 }, 521 } 522 a.Config.Platform.BareMetal.Hosts = append(a.Config.Platform.BareMetal.Hosts, host) 523 return a 524 } 525 526 func getInstallConfigSameMac() *agentAsset.OptionalInstallConfig { 527 var networkConfigSameMac = `interfaces: 528 - ipv4: 529 address: 530 - ip: 192.168.111.81 531 prefix-length: 24 532 dhcp: false 533 enabled: true 534 mac-address: 28:d2:44:b0:bf:01 535 name: eth0 536 state: up 537 type: ethernet 538 ` 539 a := getInstallConfigMultiHost() 540 a.Config.Platform.BareMetal.Hosts[1].BootMACAddress = "28:d2:44:b0:bf:01" 541 a.Config.Platform.BareMetal.Hosts[1].NetworkConfig = &apiextv1.JSON{ 542 Raw: []byte(networkConfigSameMac), 543 } 544 return a 545 } 546 547 func getInstallConfigInvalidInterfaces() *agentAsset.OptionalInstallConfig { 548 var networkConfigSameMacSameHost = `interfaces: 549 - ipv4: 550 address: 551 - ip: 192.168.111.80 552 prefix-length: 24 553 dhcp: false 554 enabled: true 555 mac-address: 28:d2:44:b0:bf:01 556 name: eth0 557 state: up 558 type: ethernet 559 - ipv4: 560 address: 561 - ip: 192.168.111.81 562 prefix-length: 24 563 dhcp: false 564 enabled: true 565 mac-address: 28:d2:44:b0:bf:01 566 name: eth0 567 state: up 568 type: ethernet 569 ` 570 a := getInstallConfigSingleHost() 571 a.Config.Platform.BareMetal.Hosts[0].NetworkConfig = &apiextv1.JSON{ 572 Raw: []byte(networkConfigSameMacSameHost), 573 } 574 return a 575 } 576 577 func getInstallConfigUnsupportedWWNExtension() *agentAsset.OptionalInstallConfig { 578 a := getInstallConfigSingleHost() 579 a.Config.Platform.BareMetal.Hosts[0].RootDeviceHints = &baremetal.RootDeviceHints{ 580 WWNWithExtension: "wwn-with-extension-value", 581 } 582 return a 583 } 584 585 func getInstallConfigNoHostnameOrRole() *agentAsset.OptionalInstallConfig { 586 a := getInstallConfigSingleHost() 587 a.Config.Platform.BareMetal.Hosts[0].Name = "" 588 a.Config.Platform.BareMetal.Hosts[0].Role = "" 589 return a 590 } 591 592 func getInstallConfigInvalidRendezvousIP() *agentAsset.OptionalInstallConfig { 593 a := getInstallConfigSingleHost() 594 a.Config.Platform.BareMetal.Hosts[0].NetworkConfig = &apiextv1.JSON{ 595 Raw: []byte(installNetworkConfigOne), 596 } 597 a.Config.Platform.BareMetal.Hosts[0].Role = "worker" 598 return a 599 } 600 601 // AgentConfigBuilder it's a builder class to make it easier creating agent.Config instance 602 // used in the test cases. 603 type AgentHostsBuilder struct { 604 AgentHosts 605 } 606 607 func agentHosts() *AgentHostsBuilder { 608 return &AgentHostsBuilder{ 609 AgentHosts: AgentHosts{ 610 Hosts: []agent.Host{{}}, 611 }, 612 } 613 } 614 615 func (ahb *AgentHostsBuilder) build() *AgentHosts { 616 return &ahb.AgentHosts 617 } 618 619 func (ahb *AgentHostsBuilder) hosts(builders ...*HostBuilder) *AgentHostsBuilder { 620 hosts := []agent.Host{} 621 for _, b := range builders { 622 hosts = append(hosts, *b.build()) 623 } 624 ahb.Hosts = hosts 625 626 return ahb 627 } 628 629 // HostBuilder it's a builder class to make it easier creating agent.Host instances 630 // used in the test cases, as part of the AgentHosts type. 631 type HostBuilder struct { 632 agent.Host 633 } 634 635 func agentHost() *HostBuilder { 636 return &HostBuilder{} 637 } 638 639 func (hb *HostBuilder) build() *agent.Host { 640 return &hb.Host 641 } 642 643 func (hb *HostBuilder) name(name string) *HostBuilder { 644 hb.Host.Hostname = name 645 return hb 646 } 647 648 func (hb *HostBuilder) role(role string) *HostBuilder { 649 hb.Host.Role = role 650 return hb 651 } 652 653 func (hb *HostBuilder) interfaces(builders ...*InterfacetBuilder) *HostBuilder { 654 ifaces := []*aiv1beta1.Interface{} 655 for _, b := range builders { 656 ifaces = append(ifaces, b.build()) 657 } 658 hb.Host.Interfaces = ifaces 659 return hb 660 } 661 662 func (hb *HostBuilder) networkConfig(raw string) *HostBuilder { 663 hb.Host.NetworkConfig = aiv1beta1.NetConfig{ 664 Raw: unmarshalJSON([]byte(raw)), 665 } 666 return hb 667 } 668 669 func (hb *HostBuilder) deviceHint() *HostBuilder { 670 hb.Host.RootDeviceHints = baremetal.RootDeviceHints{ 671 DeviceName: "/dev/sda", 672 } 673 return hb 674 } 675 676 // InterfacetBuilder it's a builder class to make it easier creating aiv1beta1.Interface instances 677 // used in the test cases, as part of the agent.Config type. 678 type InterfacetBuilder struct { 679 aiv1beta1.Interface 680 } 681 682 func iface(name string, mac string) *InterfacetBuilder { 683 return &InterfacetBuilder{ 684 Interface: aiv1beta1.Interface{ 685 Name: name, 686 MacAddress: mac, 687 }, 688 } 689 } 690 691 func (ib *InterfacetBuilder) build() *aiv1beta1.Interface { 692 return &ib.Interface 693 }