From 31c4d47ee60b06e570a8e94e3f02a8cd900ad69f Mon Sep 17 00:00:00 2001 From: Matt Proud Date: Thu, 7 Dec 2023 15:39:42 +0000 Subject: [PATCH 1/4] simplified driver subproducts --- sdk/eula_test.go | 6 +++--- sdk/subproduct_test.go | 20 +++++++++++++++----- sdk/subproducts.go | 28 ++++++++++++---------------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/sdk/eula_test.go b/sdk/eula_test.go index 523d655..d33b735 100644 --- a/sdk/eula_test.go +++ b/sdk/eula_test.go @@ -15,7 +15,7 @@ func TestFetchEulaLink(t *testing.T) { require.Nil(t, err) var eulaUrl string - eulaUrl, err = authenticatedClient.FetchEulaUrl("VMTOOLS1126", "1073") + eulaUrl, err = authenticatedClient.FetchEulaUrl("VMTOOLS1235", "1259") assert.Nil(t, err) assert.NotEmpty(t, eulaUrl, "Expected eulaUrl not be empty") } @@ -25,7 +25,7 @@ func TestFetchEulaLinkInvalidCode(t *testing.T) { assert.Nil(t, err) var eulaUrl string - eulaUrl, err = authenticatedClient.FetchEulaUrl("VMTOOLS1130", "9999") + eulaUrl, err = authenticatedClient.FetchEulaUrl("VMTOOLS1235", "9999") assert.NotNil(t, err) assert.ErrorIs(t, err, ErrorDlgDetailsInputs) assert.Empty(t, eulaUrl, "Expected eulaUrl be empty") @@ -35,6 +35,6 @@ func TestAcceptEula(t *testing.T) { err = ensureLogin(t) require.Nil(t, err) - err = authenticatedClient.AcceptEula("VMTOOLS1126", "1073") + err = authenticatedClient.AcceptEula("VMTOOLS1235", "1259") assert.Nil(t, err) } diff --git a/sdk/subproduct_test.go b/sdk/subproduct_test.go index 2cdaf2e..00c4ec4 100644 --- a/sdk/subproduct_test.go +++ b/sdk/subproduct_test.go @@ -128,23 +128,33 @@ func TestModifyHorizonClientCode(t *testing.T) { func TestGetProductName(t *testing.T) { reEndVersion := regexp.MustCompile(`[0-9]+.*`) productName := "VMware vSphere Hypervisor (ESXi) 8.0U2" - productName = getProductName(productName, "vmware_vsphere", "", reEndVersion) + productName = getProductName(productName, "vmware_vsphere", "PRODUCT_BINARY", reEndVersion) assert.Equal(t, "VMware vSphere Hypervisor (ESXi)", productName) // Ensure drivers are unmodified productName = "VMware ESXi 8.0 native ixgben ENS 1.18.2.0 NIC Driver for Intel Ethernet Controllers 82599, x520, x540, x550, and x552 family" - productName = getProductName(productName, "vmware_vsphere", "Driver CDs", reEndVersion) - assert.Equal(t, productName, "Driver - native ixgben ENS") + productName = getProductName(productName, "vmware_vsphere", "DRIVERS_TOOLS", reEndVersion) + assert.Equal(t, productName, "VMware ESXi 8.0 native ixgben ENS 1.18.2.0 NIC Driver for Intel Ethernet Controllers 82599, x520, x540, x550, and x552 family") + + // Ensure drivers are unmodified + productName = "HPE Custom Image for ESXi 7.0 U3 Install CD" + productName = getProductName(productName, "vmware_vsphere", "ADDONS", reEndVersion) + assert.Equal(t, productName, "HPE Custom Image for ESXi 7.0 U3 Install CD") } func TestGetProductCode(t *testing.T) { reEndVersion := regexp.MustCompile(`[0-9]+.*`) productCode := "ESXI80U2" - productCode = getProductCode(productCode, "vmware_vsphere", "", reEndVersion) + productCode = getProductCode(productCode, "vmware_vsphere", "PRODUCT_BINARY", reEndVersion) assert.Equal(t, "esxi", productCode) // Ensure drivers are unmodified productCode = "DT-ESXI80-INTEL-I40EN-2650-1OEM" - productCode = getProductCode(productCode, "vmware_vsphere", "Driver CDs", reEndVersion) + productCode = getProductCode(productCode, "vmware_vsphere", "DRIVERS_TOOLS", reEndVersion) assert.Equal(t, "dt-esxi80-intel-i40en-2650-1oem", productCode) + + // Ensure custom isos are unmodified + productCode = "OEM-ESXI70U3-HPE" + productCode = getProductCode(productCode, "vmware_vsphere", "ADDONS", reEndVersion) + assert.Equal(t, "oem-esxi70u3-hpe", productCode) } \ No newline at end of file diff --git a/sdk/subproducts.go b/sdk/subproducts.go index 99c8d79..7c02d1a 100644 --- a/sdk/subproducts.go +++ b/sdk/subproducts.go @@ -5,7 +5,6 @@ package sdk import ( "errors" - "fmt" "regexp" "sort" "strings" @@ -62,8 +61,8 @@ func (c *Client) GetSubProductsMap(slug, dlgType string) (subProductMap map[stri // Regex captures numbers and all text after reEndVersion := regexp.MustCompile(`[0-9]+.*`) - productName := getProductName(dlgList.Name, slug, dlgEdition.Name, reEndVersion) - productCode := getProductCode(strings.ToLower(dlgList.Code), slug, dlgEdition.Name, reEndVersion) + productName := getProductName(dlgList.Name, slug, dlgType, reEndVersion) + productCode := getProductCode(strings.ToLower(dlgList.Code), slug, dlgType, reEndVersion) // Initalize the struct for a product code for the first time if _, ok := subProductMap[productCode]; !ok { @@ -85,16 +84,16 @@ func (c *Client) GetSubProductsMap(slug, dlgType string) (subProductMap map[stri return } -func getProductCode(productCode, slug, dlgEditionName string, reEndVersion *regexp.Regexp) (string) { +func getProductCode(productCode, slug, dlgType string, reEndVersion *regexp.Regexp) (string) { productCode = strings.ToLower(productCode) + if dlgType != "PRODUCT_BINARY" { + return productCode + } reMidVersion := regexp.MustCompile(`(-|_)([0-9.]+)(-|_)`) - // Horizon clients don't follow a common pattern for API naming. This block aligns the pattern if strings.HasPrefix(productCode, "cart") { return modifyHorizonClientCode(productCode) - } - if slug == "vmware_vsphere" && dlgEditionName == "Driver CDs" { - return productCode - } + } + // Horizon clients don't follow a common pattern for API naming. This block aligns the pattern // Check if product code has text after the version section if ok := reMidVersion.MatchString(productCode); ok{ // replace version with + to allow for string to be split when searching @@ -110,22 +109,19 @@ func getProductCode(productCode, slug, dlgEditionName string, reEndVersion *rege return productCode } -func getProductName(productName, slug, dlgEditionName string, reEndVersion *regexp.Regexp) (string) { +func getProductName(productName, slug, dlgType string, reEndVersion *regexp.Regexp) (string) { + if dlgType != "PRODUCT_BINARY" { + return productName + } // Special case for Horizon due to inconsistent naming if slug == "vmware_horizon" { reNumbers := regexp.MustCompile(`[0-9.,]+`) reSpace := regexp.MustCompile(`\s+`) productName := strings.TrimSpace(reNumbers.ReplaceAllString(productName, "")) return reSpace.ReplaceAllString(productName, " ") - // Special case for ESXi drivers to make human readable - } else if slug == "vmware_vsphere" && dlgEditionName == "Driver CDs" { - stripEsx := regexp.MustCompile(`VMware ESXi [0-9]+.[0-9]+ `) - productName = fmt.Sprintf("Driver - %s", stripEsx.ReplaceAllString(productName, "")) - return strings.TrimSpace(reEndVersion.ReplaceAllString(productName, "")) } else { return strings.TrimSpace(reEndVersion.ReplaceAllString(productName, "")) } - } func modifyHorizonClientCode(productCode string) (string) { From d55c08306d1b555ffa3f6ef8fd0b76ac1d819db1 Mon Sep 17 00:00:00 2001 From: Matt Proud Date: Fri, 8 Dec 2023 11:22:28 +0000 Subject: [PATCH 2/4] added major version base existing code working --- sdk/subproduct_test.go | 35 ++++++++++++++++++++--------------- sdk/subproducts.go | 19 +++++++++++++------ 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/sdk/subproduct_test.go b/sdk/subproduct_test.go index 00c4ec4..d577271 100644 --- a/sdk/subproduct_test.go +++ b/sdk/subproduct_test.go @@ -12,16 +12,28 @@ import ( func TestGetSubProductsSlice(t *testing.T) { var subProducts []SubProductDetails - subProducts, err = basicClient.GetSubProductsSlice("vmware_horizon", "PRODUCT_BINARY") + subProducts, err = basicClient.GetSubProductsSlice("vmware_horizon", "PRODUCT_BINARY", "") assert.Nil(t, err) assert.GreaterOrEqual(t, len(subProducts), 20, "Expected response to contain at least 20 items") } func TestGetSubProductsSliceDrivers(t *testing.T) { var subProducts []SubProductDetails - subProducts, err = basicClient.GetSubProductsSlice("vmware_vsphere", "DRIVERS_TOOLS") + subProducts, err = basicClient.GetSubProductsSlice("vmware_vsphere", "DRIVERS_TOOLS", "") assert.Nil(t, err) - assert.GreaterOrEqual(t, len(subProducts), 20, "Expected response to contain at least 20 items") + assert.GreaterOrEqual(t, len(subProducts), 200, "Expected response to contain at least 200 items") + + // Ensure less results are returned after specifying majpor version + subProducts, err = basicClient.GetSubProductsSlice("vmware_vsphere", "DRIVERS_TOOLS", "8_0") + assert.Nil(t, err) + assert.LessOrEqual(t, len(subProducts), 400, "Expected response to contain less than 400 items") +} + +func TestGetSubProductsSliceInvalidSlug(t *testing.T) { + var subProducts []SubProductDetails + subProducts, err = basicClient.GetSubProductsSlice("vsphere", "PRODUCT_BINARY", "") + assert.ErrorIs(t, err, ErrorInvalidSlug) + assert.Empty(t, subProducts, "Expected response to be empty") } func TestGetSubProductNsxLE(t *testing.T) { @@ -46,23 +58,16 @@ func TestGetSubProductDriver(t *testing.T) { assert.NotEmpty(t, subProduct.ProductName) } -func TestGetSubProductsSliceInvalidSlug(t *testing.T) { - var subProducts []SubProductDetails - subProducts, err = basicClient.GetSubProductsSlice("vsphere", "PRODUCT_BINARY") - assert.ErrorIs(t, err, ErrorInvalidSlug) - assert.Empty(t, subProducts, "Expected response to be empty") -} - func TestGetSubProductsMap(t *testing.T) { var subProducts map[string]SubProductDetails - subProducts, err = basicClient.GetSubProductsMap("vmware_vsphere", "PRODUCT_BINARY") + subProducts, err = basicClient.GetSubProductsMap("vmware_vsphere", "PRODUCT_BINARY", "") assert.Nil(t, err) assert.Contains(t, subProducts, "vmtools") } func TestGetSubProductsMapHorizon(t *testing.T) { var subProducts map[string]SubProductDetails - subProducts, err = basicClient.GetSubProductsMap("vmware_horizon_clients", "PRODUCT_BINARY") + subProducts, err = basicClient.GetSubProductsMap("vmware_horizon_clients", "PRODUCT_BINARY", "") assert.Nil(t, err) assert.Contains(t, subProducts, "cart+win") assert.Contains(t, subProducts, "cart+andrd_x8632") @@ -71,7 +76,7 @@ func TestGetSubProductsMapHorizon(t *testing.T) { func TestGetSubProductsMapNsxLe(t *testing.T) { var subProducts map[string]SubProductDetails - subProducts, err = basicClient.GetSubProductsMap("vmware_nsx", "PRODUCT_BINARY") + subProducts, err = basicClient.GetSubProductsMap("vmware_nsx", "PRODUCT_BINARY", "") assert.Nil(t, err) assert.Contains(t, subProducts, "nsx") assert.Contains(t, subProducts, "nsx_le") @@ -79,7 +84,7 @@ func TestGetSubProductsMapNsxLe(t *testing.T) { func TestGetSubProductsMapNsxTLe(t *testing.T) { var subProducts map[string]SubProductDetails - subProducts, err = basicClient.GetSubProductsMap("vmware_nsx_t_data_center", "PRODUCT_BINARY") + subProducts, err = basicClient.GetSubProductsMap("vmware_nsx_t_data_center", "PRODUCT_BINARY", "") assert.Nil(t, err) assert.Contains(t, subProducts, "nsx-t") assert.Contains(t, subProducts, "nsx-t_le") @@ -87,7 +92,7 @@ func TestGetSubProductsMapNsxTLe(t *testing.T) { func TestGetSubProductsMapInvalidSlug(t *testing.T) { var subProductMap map[string]SubProductDetails - subProductMap, err = basicClient.GetSubProductsMap("vsphere", "PRODUCT_BINARY") + subProductMap, err = basicClient.GetSubProductsMap("vsphere", "PRODUCT_BINARY", "" ) assert.ErrorIs(t, err, ErrorInvalidSlug) assert.Empty(t, subProductMap, "Expected response to be empty") } diff --git a/sdk/subproducts.go b/sdk/subproducts.go index 7c02d1a..75bef8e 100644 --- a/sdk/subproducts.go +++ b/sdk/subproducts.go @@ -6,6 +6,7 @@ package sdk import ( "errors" "regexp" + "slices" "sort" "strings" ) @@ -24,7 +25,7 @@ type SubProductSliceElement struct { var ErrorInvalidSubProduct = errors.New("subproduct: invalid subproduct requested") var ErrorInvalidSubProductMajorVersion = errors.New("subproduct: invalid major version requested") -func (c *Client) GetSubProductsMap(slug, dlgType string) (subProductMap map[string]SubProductDetails, err error) { +func (c *Client) GetSubProductsMap(slug, dlgType, requestedMajorVersion string) (subProductMap map[string]SubProductDetails, err error) { c.EnsureProductDetailMap() if err != nil { return @@ -42,6 +43,13 @@ func (c *Client) GetSubProductsMap(slug, dlgType string) (subProductMap map[stri if err != nil { return } + if requestedMajorVersion != "" { + if !slices.Contains(majorVersions, requestedMajorVersion) { + err = ErrorInvalidSubProductMajorVersion + return + } + //TODO perform logic + } // Iterate major product versions and extract all unique products // All version information is stripped @@ -160,9 +168,8 @@ func duplicateNsxToNsxLe(subProductMap map[string]SubProductDetails, productCode subProductMap[productCode + "_le"].DlgListByVersion[majorVersion] = dlgList } - -func (c *Client) GetSubProductsSlice(slug, dlgType string) (data []SubProductDetails, err error) { - subProductMap, err := c.GetSubProductsMap(slug, dlgType) +func (c *Client) GetSubProductsSlice(slug, dlgType, majorVersion string) (data []SubProductDetails, err error) { + subProductMap, err := c.GetSubProductsMap(slug, dlgType, majorVersion) if err != nil { return } @@ -186,7 +193,7 @@ func (c *Client) GetSubProductsSlice(slug, dlgType string) (data []SubProductDet func (c *Client) GetSubProduct(slug, subProduct, dlgType string) (data SubProductDetails, err error) { var subProductMap map[string]SubProductDetails - subProductMap, err = c.GetSubProductsMap(slug, dlgType) + subProductMap, err = c.GetSubProductsMap(slug, dlgType, "") if err != nil { return } @@ -202,7 +209,7 @@ func (c *Client) GetSubProduct(slug, subProduct, dlgType string) (data SubProduc func (c *Client) GetSubProductDetails(slug, subProduct, majorVersion, dlgType string) (data DlgList, err error) { var subProducts map[string]SubProductDetails - subProducts, err = c.GetSubProductsMap(slug, dlgType) + subProducts, err = c.GetSubProductsMap(slug, dlgType, "") if err != nil { return } From 0d1c00bdc43a6ce1e0981da9a474957f7df46a50 Mon Sep 17 00:00:00 2001 From: Matt Proud Date: Fri, 8 Dec 2023 11:41:26 +0000 Subject: [PATCH 3/4] finished logic to process a single major version for a subproduct --- sdk/subproduct_test.go | 12 +++--------- sdk/subproducts.go | 40 +++++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/sdk/subproduct_test.go b/sdk/subproduct_test.go index d577271..514d998 100644 --- a/sdk/subproduct_test.go +++ b/sdk/subproduct_test.go @@ -21,11 +21,12 @@ func TestGetSubProductsSliceDrivers(t *testing.T) { var subProducts []SubProductDetails subProducts, err = basicClient.GetSubProductsSlice("vmware_vsphere", "DRIVERS_TOOLS", "") assert.Nil(t, err) - assert.GreaterOrEqual(t, len(subProducts), 200, "Expected response to contain at least 200 items") - + assert.GreaterOrEqual(t, len(subProducts), 400, "Expected response to contain at least 200 items") + // Ensure less results are returned after specifying majpor version subProducts, err = basicClient.GetSubProductsSlice("vmware_vsphere", "DRIVERS_TOOLS", "8_0") assert.Nil(t, err) + assert.GreaterOrEqual(t, len(subProducts), 100, "Expected response to contain at least 100 items") assert.LessOrEqual(t, len(subProducts), 400, "Expected response to contain less than 400 items") } @@ -44,13 +45,6 @@ func TestGetSubProductNsxLE(t *testing.T) { assert.Greater(t, len(subProduct.DlgListByVersion), 0) } -// func TestGetSubProduct(t *testing.T) { -// var subProduct SubProductDetails -// subProduct, err = basicClient.GetSubProduct("vmware_vsphere", "dem+standard", "PRODUCT_BINARY") -// assert.Nil(t, err) -// assert.NotEmpty(t, subProduct.ProductName) -// } - func TestGetSubProductDriver(t *testing.T) { var subProduct SubProductDetails subProduct, err = basicClient.GetSubProduct("vmware_horizon", "dem+standard", "PRODUCT_BINARY") diff --git a/sdk/subproducts.go b/sdk/subproducts.go index 75bef8e..1c8bb8d 100644 --- a/sdk/subproducts.go +++ b/sdk/subproducts.go @@ -30,37 +30,48 @@ func (c *Client) GetSubProductsMap(slug, dlgType, requestedMajorVersion string) if err != nil { return } - if _, ok := ProductDetailMap[slug]; !ok { err = ErrorInvalidSlug return } - - subProductMap = make(map[string]SubProductDetails) - var majorVersions []string majorVersions, err = c.GetMajorVersionsSlice(slug) if err != nil { return } + + subProductMap = make(map[string]SubProductDetails) + + // Only process requested major version, otherwise process all for slug if requestedMajorVersion != "" { if !slices.Contains(majorVersions, requestedMajorVersion) { err = ErrorInvalidSubProductMajorVersion return } - //TODO perform logic + err = c.processMajorVersion(slug, requestedMajorVersion, dlgType, subProductMap) + if err != nil { + return + } + } else { + // Iterate major product versions and extract all unique products + // All version information is stripped + for _, majorVersion := range majorVersions { + c.processMajorVersion(slug, majorVersion, dlgType, subProductMap) + // Invalid version errors need to be ignored, as they come from deprecated products + if err == ErrorInvalidVersion { + err = nil + } else if err != nil { + return + } + } } + return +} - // Iterate major product versions and extract all unique products - // All version information is stripped - for _, majorVersion := range majorVersions { - var dlgEditionsList []DlgEditionsLists +func (c *Client) processMajorVersion (slug, majorVersion, dlgType string, subProductMap map[string]SubProductDetails) (err error) { + var dlgEditionsList []DlgEditionsLists dlgEditionsList, err = c.GetDlgEditionsList(slug, majorVersion, dlgType) - // Invalid version errors need to be ignored, as they come from deprecated products - if err == ErrorInvalidVersion { - err = nil - continue - } else if err != nil { + if err != nil { return } @@ -88,7 +99,6 @@ func (c *Client) GetSubProductsMap(slug, dlgType, requestedMajorVersion string) } } } - } return } From 48fe924cf228d60e2ec8d50cf51dabe47e51d161 Mon Sep 17 00:00:00 2001 From: Matt Proud Date: Fri, 8 Dec 2023 11:49:13 +0000 Subject: [PATCH 4/4] bump go version in actions --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b04b3d0..52a6d28 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,7 +24,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.19.5 + go-version: 1.21.4 - name: Checkout Code uses: actions/checkout@v3