HewlettPackard / terraform-provider-oneview

Automates the provisioning of physical infrastructure from a private cloud using templates from HPE OneView with Terraform
Apache License 2.0
49 stars 30 forks source link

Data object retrieval for firmware_drivers bug #523

Closed BoudewijnSwen closed 1 year ago

BoudewijnSwen commented 1 year ago

_providerversion = "8.1.0-13" api version = 4800

Hello,

I noticed a small problem in the way oneview_firmware_drivers data objects are retrieved.

I suspect it's because in the SSPs for Gen10's there is an extra space at the end of the name and the way the provider parses the id field of the data objects for oneview_firmware_drivers. The fix should also be fairly easy.

Problem: Let me explain by showing what happens. We have OV running in 3 different environments, on the same version, and this problem is consistently happening in all of them.

OneView UI shows the following under firmware bundles: "Service Pack for ProLiant, 2021.05.0" "Gen9 Service Pack for ProLiant, 2021.10.1" "Gen10 Service Pack for ProLiant , 2021.10.0" "Gen10 Service Pack for ProLiant , 2022.03.0"

In the API there is no field that has the above names as 1 value. So I assume it's a combined value of the 2 fields below: "name": "Gen10 Service Pack for ProLiant " "version": "2021.10.0"

I believe data object retrieval was done with uuid's or something some time ago. But this was changed to these UI names instead. So the 4 bundles listed above I should retrieve as follows:

# "Service Pack for ProLiant, 2021.05.0"
data "oneview_firmware_drivers" "gen9_hpe_service_pack_2021_05_0" {
  id = "Service Pack for ProLiant, 2021.05.0"
}

# "Gen9 Service Pack for ProLiant, 2021.10.1"
data "oneview_firmware_drivers" "gen9_hpe_service_pack_2021_10_1" {
  id = "Gen9 Service Pack for ProLiant, 2021.10.1"
}

# "Gen10 Service Pack for ProLiant , 2021.10.0"
data "oneview_firmware_drivers" "gen10_hpe_service_pack_2021_10_0" {
  id = "Gen10 Service Pack for ProLiant , 2021.10.0"
}

# "Gen10 Service Pack for ProLiant , 2022.03.0"
data "oneview_firmware_drivers" "gen10_hpe_service_pack_2022_03_0" {
  id = "Gen10 Service Pack for ProLiant , 2022.03.0"
}

When I output values for these:

output "gen9_2021_05" {
    value = data.oneview_firmware_drivers.gen9_hpe_service_pack_2021_05_0.uri
}
output "gen9_2021_10_1" {
    value = data.oneview_firmware_drivers.gen9_hpe_service_pack_2021_10_1.uri
}
output "gen10_2021_10" {
    value = data.oneview_firmware_drivers.gen10_hpe_service_pack_2021_10_0.uri
}
output "gen10_2022_03" {
    value = data.oneview_firmware_drivers.gen10_hpe_service_pack_2022_03_0.uri
}

Changes to Outputs:
  + gen9_2021_05   = "/rest/firmware-drivers/P35938_001_spp-2021_05_0-SPP2021050_2021_0504_129"
  + gen9_2021_10_1 = "/rest/firmware-drivers/P45315_001_gen9spp-2021_10_1-Gen9SPP2021101_2022_0711_2"

I only get responses for the Gen9 bundles:

If I remove the '.uri' part, I can see that I get empty objects back with all null values for the Gen10 bundles.

If I only specify the name (with the extra space) and no version, as the ID for a Gen10 firmware data object:

data "oneview_firmware_drivers" "gen10_hpe_service_pack" {
  id = "Gen10 Service Pack for ProLiant "
}
output "gen10" {
    value = data.oneview_firmware_drivers.gen10_hpe_service_pack.uri
}

Changes to Outputs:
  + gen10          = "/rest/firmware-drivers/P45316_001_gen10spp-2021_10_0-SPP2021100_2021_1012_13"

I do get a response, it returned the oldest version.

Result: So I cannot specify which version of the firmware I want to retrieve (and use for my server_profile(_templates)) for Gen10 firmware bundles, because all of the Gen10 firmware bundles have this extra space at the end of the name.

Solution: My Go skills are not great (read: non existent :P), but I can see that the in firmware_drivers.go the following function does a split on the comma and than trims all spaces. Which is most likely the problem... since all these Gen10 SSPs have a extra space at the end of the name.

func (c *OVClient) GetFirmwareBaselineByNameandVersion(name string) (FirmwareDrivers, error) {
    var fwname, version string
    fwNameVersion := strings.Split(name, ",")
    if len(fwNameVersion) == 0 {
        return FirmwareDrivers{}, errors.New("firmware name not provided")
    }
    if len(fwNameVersion) == 2 {
        fwname, version = strings.TrimSpace(fwNameVersion[0]), strings.TrimSpace(fwNameVersion[1])
        if fwname == "" {
            return FirmwareDrivers{}, errors.New("firmware name not found in the name")
        }
    } else {
        fwname = fwNameVersion[0]
    }

Hopefully this helps!

I will try and implement a workaround for now, by exporting vars containing the hardcoded firmware bundle uris for each environment, and referencing those vars in my server profile templates, so my tf plan is still portable between environments.

nabhajit-ray commented 1 year ago

Hi,thanks for sharing all the details. We will check and get back to you

nabhajit-ray commented 1 year ago

This is fixed in main branch.

Use datasource like below:

data "oneview_firmware_drivers" "test" { name= "HPE Synergy Service Pack" version="SY-2021.11.01" }