diff --git a/go.mod b/go.mod index c4b8dfbad7..69f0b396f6 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/go-logr/logr v1.3.0 github.com/google/safetext v0.0.0-20230106111101-7156a760e523 - github.com/gophercloud/gophercloud v1.5.1-0.20231106162611-af1813efe0d1 + github.com/gophercloud/gophercloud v1.5.1-0.20231117122435-08456f7fe42e github.com/metal3-io/baremetal-operator/apis v0.4.0 github.com/metal3-io/baremetal-operator/pkg/hardwareutils v0.4.0 github.com/onsi/gomega v1.30.0 @@ -62,7 +62,7 @@ require ( golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.14.0 // indirect golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect diff --git a/go.sum b/go.sum index 6571f6edba..c470351ea9 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,8 @@ github.com/google/safetext v0.0.0-20230106111101-7156a760e523 h1:i4NsbmB9pD5+Ggp github.com/google/safetext v0.0.0-20230106111101-7156a760e523/go.mod h1:mJNEy0r5YPHC7ChQffpOszlGB4L1iqjXWpIEKcFpr9s= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gophercloud/gophercloud v1.5.1-0.20231106162611-af1813efe0d1 h1:4crYiUFYzhxv60/bsLnyc7esUsOqQl3DgErAGNsOgL8= -github.com/gophercloud/gophercloud v1.5.1-0.20231106162611-af1813efe0d1/go.mod h1:99P1GdytPKaSR7/ugQJo1dX6th5FlHdXXvKqvRJQfO4= +github.com/gophercloud/gophercloud v1.5.1-0.20231117122435-08456f7fe42e h1:acHzJUXVfS+GImmi+yyM2+AOiaO94Z4KaTTFVU6Ov9U= +github.com/gophercloud/gophercloud v1.5.1-0.20231117122435-08456f7fe42e/go.mod h1:ecnaHbFxBunc2UeAONDQbkQacv6WP1syeZ02TgAB7kA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= @@ -197,8 +197,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= diff --git a/pkg/hardwareutils/bmc/access.go b/pkg/hardwareutils/bmc/access.go index 960b9effb5..f00770f6c9 100644 --- a/pkg/hardwareutils/bmc/access.go +++ b/pkg/hardwareutils/bmc/access.go @@ -74,6 +74,9 @@ type AccessDetails interface { RAIDInterface() string VendorInterface() string + // Firmware interface to set + FirmwareInterface() string + // Whether the driver supports changing secure boot state. SupportsSecureBoot() bool diff --git a/pkg/hardwareutils/bmc/access_test.go b/pkg/hardwareutils/bmc/access_test.go index b0f5ac1a14..2ed2a31947 100644 --- a/pkg/hardwareutils/bmc/access_test.go +++ b/pkg/hardwareutils/bmc/access_test.go @@ -464,6 +464,7 @@ func TestStaticDriverInfo(t *testing.T) { driver string bios string boot string + firmware string management string power string vendor string @@ -475,6 +476,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "ipmi", bios: "", boot: "ipxe", + firmware: "", management: "", power: "", }, @@ -486,6 +488,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "ipmi", bios: "", boot: "ipxe", + firmware: "", management: "", power: "", }, @@ -497,6 +500,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "idrac", bios: "", boot: "ipxe", + firmware: "", management: "", power: "", }, @@ -508,6 +512,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "irmc", bios: "", boot: "ipxe", + firmware: "", management: "", power: "", }, @@ -519,6 +524,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "redfish", bios: "", boot: "ipxe", + firmware: "redfish", management: "", power: "", }, @@ -530,6 +536,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "redfish", bios: "", boot: "redfish-virtual-media", + firmware: "redfish", management: "", power: "", }, @@ -541,6 +548,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "redfish", bios: "", boot: "redfish-virtual-media", + firmware: "redfish", management: "", power: "", }, @@ -552,6 +560,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "redfish", bios: "", boot: "redfish-virtual-media", + firmware: "redfish", management: "", power: "", }, @@ -563,6 +572,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "idrac", bios: "idrac-redfish", boot: "ipxe", + firmware: "redfish", management: "idrac-redfish", power: "idrac-redfish", vendor: "idrac-redfish", @@ -575,6 +585,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "redfish", bios: "", boot: "redfish-virtual-media", + firmware: "redfish", }, { @@ -584,6 +595,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "redfish", bios: "", boot: "redfish-virtual-media", + firmware: "redfish", }, { @@ -593,6 +605,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "redfish", bios: "", boot: "redfish-virtual-media", + firmware: "redfish", }, { @@ -602,6 +615,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "idrac", bios: "idrac-redfish", boot: "idrac-redfish-virtual-media", + firmware: "redfish", management: "idrac-redfish", power: "idrac-redfish", vendor: "idrac-redfish", @@ -614,6 +628,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "idrac", bios: "idrac-redfish", boot: "idrac-redfish-virtual-media", + firmware: "redfish", management: "idrac-redfish", power: "idrac-redfish", vendor: "idrac-redfish", @@ -626,6 +641,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "idrac", bios: "idrac-redfish", boot: "idrac-redfish-virtual-media", + firmware: "redfish", management: "idrac-redfish", power: "idrac-redfish", vendor: "idrac-redfish", @@ -638,6 +654,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "ibmc", bios: "", boot: "ipxe", + firmware: "", management: "ibmc", power: "ibmc", }, @@ -649,6 +666,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "ilo", bios: "", boot: "ilo-ipxe", + firmware: "", management: "", power: "", }, @@ -660,6 +678,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "ilo", bios: "", boot: "ilo-virtual-media", + firmware: "", management: "", power: "", }, @@ -671,6 +690,7 @@ func TestStaticDriverInfo(t *testing.T) { driver: "ilo5", bios: "", boot: "ilo-ipxe", + firmware: "", management: "", power: "", }, @@ -694,6 +714,10 @@ func TestStaticDriverInfo(t *testing.T) { t.Fatalf("Unexpected bios interface %q, expected %q", acc.BIOSInterface(), tc.bios) } + if acc.FirmwareInterface() != tc.firmware { + t.Fatalf("Unexpected firmware interface %q, expected %q", + acc.FirmwareInterface(), tc.firmware) + } if acc.VendorInterface() != tc.vendor { t.Fatalf("Unexpected vendor interface %q, expected %q", acc.VendorInterface(), tc.vendor) diff --git a/pkg/hardwareutils/bmc/ibmc.go b/pkg/hardwareutils/bmc/ibmc.go index 7cb4b9afe5..01e85d8dda 100644 --- a/pkg/hardwareutils/bmc/ibmc.go +++ b/pkg/hardwareutils/bmc/ibmc.go @@ -87,6 +87,10 @@ func (a *ibmcAccessDetails) BootInterface() string { return "ipxe" } +func (a *ibmcAccessDetails) FirmwareInterface() string { + return "" +} + func (a *ibmcAccessDetails) ManagementInterface() string { return "ibmc" } diff --git a/pkg/hardwareutils/bmc/idrac.go b/pkg/hardwareutils/bmc/idrac.go index b7b8cb844b..bddc02677e 100644 --- a/pkg/hardwareutils/bmc/idrac.go +++ b/pkg/hardwareutils/bmc/idrac.go @@ -82,6 +82,10 @@ func (a *iDracAccessDetails) BootInterface() string { return "ipxe" } +func (a *iDracAccessDetails) FirmwareInterface() string { + return "" +} + func (a *iDracAccessDetails) ManagementInterface() string { return "" } diff --git a/pkg/hardwareutils/bmc/idrac_virtualmedia.go b/pkg/hardwareutils/bmc/idrac_virtualmedia.go index a30a2a20bb..79ffa57ed9 100644 --- a/pkg/hardwareutils/bmc/idrac_virtualmedia.go +++ b/pkg/hardwareutils/bmc/idrac_virtualmedia.go @@ -76,6 +76,10 @@ func (a *redfishiDracVirtualMediaAccessDetails) BootInterface() string { return "idrac-redfish-virtual-media" } +func (a *redfishiDracVirtualMediaAccessDetails) FirmwareInterface() string { + return "redfish" +} + func (a *redfishiDracVirtualMediaAccessDetails) ManagementInterface() string { return "idrac-redfish" } diff --git a/pkg/hardwareutils/bmc/ilo4.go b/pkg/hardwareutils/bmc/ilo4.go index bff98bc608..6ccc68b1ac 100644 --- a/pkg/hardwareutils/bmc/ilo4.go +++ b/pkg/hardwareutils/bmc/ilo4.go @@ -94,6 +94,10 @@ func (a *iLOAccessDetails) BootInterface() string { } } +func (a *iLOAccessDetails) FirmwareInterface() string { + return "" +} + func (a *iLOAccessDetails) ManagementInterface() string { return "" } diff --git a/pkg/hardwareutils/bmc/ilo5.go b/pkg/hardwareutils/bmc/ilo5.go index 2cfbee1fbf..e79bf44223 100644 --- a/pkg/hardwareutils/bmc/ilo5.go +++ b/pkg/hardwareutils/bmc/ilo5.go @@ -78,6 +78,10 @@ func (a *iLO5AccessDetails) BootInterface() string { return "ilo-ipxe" } +func (a *iLO5AccessDetails) FirmwareInterface() string { + return "" +} + func (a *iLO5AccessDetails) ManagementInterface() string { return "" } diff --git a/pkg/hardwareutils/bmc/ipmi.go b/pkg/hardwareutils/bmc/ipmi.go index c4a29d00cd..eb30a35fd9 100644 --- a/pkg/hardwareutils/bmc/ipmi.go +++ b/pkg/hardwareutils/bmc/ipmi.go @@ -97,6 +97,10 @@ func (a *ipmiAccessDetails) BootInterface() string { return "ipxe" } +func (a *ipmiAccessDetails) FirmwareInterface() string { + return "" +} + func (a *ipmiAccessDetails) ManagementInterface() string { return "" } diff --git a/pkg/hardwareutils/bmc/irmc.go b/pkg/hardwareutils/bmc/irmc.go index a9c0b789ff..f87c71472c 100644 --- a/pkg/hardwareutils/bmc/irmc.go +++ b/pkg/hardwareutils/bmc/irmc.go @@ -78,6 +78,10 @@ func (a *iRMCAccessDetails) BootInterface() string { return "ipxe" } +func (a *iRMCAccessDetails) FirmwareInterface() string { + return "" +} + func (a *iRMCAccessDetails) ManagementInterface() string { return "" } diff --git a/pkg/hardwareutils/bmc/redfish.go b/pkg/hardwareutils/bmc/redfish.go index 3032818936..21222598eb 100644 --- a/pkg/hardwareutils/bmc/redfish.go +++ b/pkg/hardwareutils/bmc/redfish.go @@ -107,6 +107,10 @@ func (a *redfishAccessDetails) BootInterface() string { return "ipxe" } +func (a *redfishAccessDetails) FirmwareInterface() string { + return "redfish" +} + func (a *redfishAccessDetails) ManagementInterface() string { return "" } @@ -155,6 +159,10 @@ func (a *redfishiDracAccessDetails) BootInterface() string { return "ipxe" } +func (a *redfishiDracAccessDetails) FirmwareInterface() string { + return "redfish" +} + func (a *redfishiDracAccessDetails) ManagementInterface() string { return "idrac-redfish" } diff --git a/pkg/hardwareutils/bmc/redfish_virtualmedia.go b/pkg/hardwareutils/bmc/redfish_virtualmedia.go index bd319d177c..bb66b6f49d 100644 --- a/pkg/hardwareutils/bmc/redfish_virtualmedia.go +++ b/pkg/hardwareutils/bmc/redfish_virtualmedia.go @@ -75,6 +75,10 @@ func (a *redfishVirtualMediaAccessDetails) BootInterface() string { return "redfish-virtual-media" } +func (a *redfishVirtualMediaAccessDetails) FirmwareInterface() string { + return "redfish" +} + func (a *redfishVirtualMediaAccessDetails) ManagementInterface() string { return "" } diff --git a/pkg/provisioner/ironic/clients/features.go b/pkg/provisioner/ironic/clients/features.go index 46452d655b..b98cc65c97 100644 --- a/pkg/provisioner/ironic/clients/features.go +++ b/pkg/provisioner/ironic/clients/features.go @@ -41,15 +41,15 @@ func (af AvailableFeatures) Log(logger logr.Logger) { logger.Info("supported Ironic API features", "maxVersion", fmt.Sprintf("1.%d", af.MaxVersion), "chosenVersion", af.ChooseMicroversion(), - "firmwareUpgrades", af.HasFirmwareUpgrades()) + "firmwareUpdates", af.HasFirmwareUpdates()) } -func (af AvailableFeatures) HasFirmwareUpgrades() bool { +func (af AvailableFeatures) HasFirmwareUpdates() bool { return af.MaxVersion >= 86 } func (af AvailableFeatures) ChooseMicroversion() string { - if af.HasFirmwareUpgrades() { + if af.HasFirmwareUpdates() { return "1.86" } diff --git a/pkg/provisioner/ironic/ironic.go b/pkg/provisioner/ironic/ironic.go index 6d8d7e210f..4c0abce6f7 100644 --- a/pkg/provisioner/ironic/ironic.go +++ b/pkg/provisioner/ironic/ironic.go @@ -367,24 +367,29 @@ func (p *ironicProvisioner) ValidateManagementAccess(data provisioner.Management return } - ironicNode, err = nodes.Create( - p.client, - nodes.CreateOpts{ - Driver: bmcAccess.Driver(), - BIOSInterface: bmcAccess.BIOSInterface(), - BootInterface: bmcAccess.BootInterface(), - Name: ironicNodeName(p.objectMeta), - DriverInfo: driverInfo, - DeployInterface: p.deployInterface(data), - InspectInterface: "inspector", - ManagementInterface: bmcAccess.ManagementInterface(), - PowerInterface: bmcAccess.PowerInterface(), - RAIDInterface: bmcAccess.RAIDInterface(), - VendorInterface: bmcAccess.VendorInterface(), - Properties: map[string]interface{}{ - "capabilities": bootModeCapabilities[data.BootMode], - }, - }).Extract() + nodeCreateOpts := nodes.CreateOpts{ + Driver: bmcAccess.Driver(), + BIOSInterface: bmcAccess.BIOSInterface(), + BootInterface: bmcAccess.BootInterface(), + Name: ironicNodeName(p.objectMeta), + DriverInfo: driverInfo, + DeployInterface: p.deployInterface(data), + FirmwareInterface: bmcAccess.FirmwareInterface(), + InspectInterface: "inspector", + ManagementInterface: bmcAccess.ManagementInterface(), + PowerInterface: bmcAccess.PowerInterface(), + RAIDInterface: bmcAccess.RAIDInterface(), + VendorInterface: bmcAccess.VendorInterface(), + Properties: map[string]interface{}{ + "capabilities": bootModeCapabilities[data.BootMode], + }, + } + + if p.availableFeatures.HasFirmwareUpdates() { + nodeCreateOpts.FirmwareInterface = bmcAccess.FirmwareInterface() + } + + ironicNode, err = nodes.Create(p.client, nodeCreateOpts).Extract() switch err.(type) { case nil: p.publisher("Registered", "Registered new host") diff --git a/pkg/provisioner/ironic/prepare_test.go b/pkg/provisioner/ironic/prepare_test.go index 1ae1c5b769..ca24f9ea2f 100644 --- a/pkg/provisioner/ironic/prepare_test.go +++ b/pkg/provisioner/ironic/prepare_test.go @@ -25,6 +25,7 @@ func (r *RAIDTestBMC) DriverInfo(bmc.Credentials) (i map[string]interface{}) { r func (r *RAIDTestBMC) SupportsISOPreprovisioningImage() bool { return false } func (r *RAIDTestBMC) BIOSInterface() string { return "" } func (r *RAIDTestBMC) BootInterface() string { return "" } +func (r *RAIDTestBMC) FirmwareInterface() string { return "" } func (r *RAIDTestBMC) ManagementInterface() string { return "" } func (r *RAIDTestBMC) PowerInterface() string { return "" } func (r *RAIDTestBMC) RAIDInterface() string { return "" } diff --git a/pkg/provisioner/ironic/testbmc/testbmc.go b/pkg/provisioner/ironic/testbmc/testbmc.go index 50a900a16c..500cd97a46 100644 --- a/pkg/provisioner/ironic/testbmc/testbmc.go +++ b/pkg/provisioner/ironic/testbmc/testbmc.go @@ -70,6 +70,10 @@ func (a *testAccessDetails) BootInterface() string { return "ipxe" } +func (a *testAccessDetails) FirmwareInterface() string { + return "" +} + func (a *testAccessDetails) ManagementInterface() string { return "" }