From ecedee0c6e130daac40e2fade07fbb60e94400cf Mon Sep 17 00:00:00 2001 From: Wayne Adams Date: Wed, 27 Nov 2024 09:05:29 -0800 Subject: [PATCH] Sends helpful error when metedata has multiple stemcell types (#678) * Sends helpful error when metedata has multiple stemcell types - Add checkForSingleStemcellType function to validate stemcell selection - Update getLatestStemcell to track all unique stemcell types - Add test case to verify error handling for multiple stemcell types Authored-by: Wayne Adams --- download_clients/pivnet_client.go | 21 ++++++++++++++++++--- download_clients/pivnet_client_test.go | 11 +++++++++++ go.mod | 1 + go.sum | 2 ++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/download_clients/pivnet_client.go b/download_clients/pivnet_client.go index cb2df1d9..a9022597 100644 --- a/download_clients/pivnet_client.go +++ b/download_clients/pivnet_client.go @@ -9,6 +9,8 @@ import ( "strconv" "strings" + "golang.org/x/exp/slices" + "github.com/pivotal-cf/go-pivnet/v6/logshim" "github.com/pivotal-cf/pivnet-cli/v2/filter" @@ -170,25 +172,38 @@ func (p *pivnetClient) checkForSingleProductFile(glob string, productFiles []piv return nil } +func (p *pivnetClient) checkForSingleStemcellType(stemcellSlugs []string) error { + if len(stemcellSlugs) > 1 { + return fmt.Errorf("multiple stemcell types found: %s", strings.Join(stemcellSlugs, ", ")) + } + return nil +} + func (p *pivnetClient) getLatestStemcell(dependencies []pivnet.ReleaseDependency) (string, string, error) { var ( - stemcellSlug string + stemcellSlugs []string versions []string ) for _, dependency := range dependencies { if strings.Contains(dependency.Release.Product.Slug, "stemcells") { - stemcellSlug = dependency.Release.Product.Slug + if !slices.Contains(stemcellSlugs, dependency.Release.Product.Slug) { + stemcellSlugs = append(stemcellSlugs, dependency.Release.Product.Slug) + } versions = append(versions, dependency.Release.Version) } } + if err := p.checkForSingleStemcellType(stemcellSlugs); err != nil { + return "", "", fmt.Errorf("could not determine stemcell: %s", err) + } + stemcellVersion, err := getLatestStemcellVersion(versions) if err != nil { return "", "", err } - return stemcellSlug, stemcellVersion, nil + return stemcellSlugs[0], stemcellVersion, nil } const ( diff --git a/download_clients/pivnet_client_test.go b/download_clients/pivnet_client_test.go index f1093850..7cbe794c 100644 --- a/download_clients/pivnet_client_test.go +++ b/download_clients/pivnet_client_test.go @@ -401,6 +401,17 @@ var _ = Describe("PivnetClient", func() { _, err := client.GetLatestStemcellForProduct(createPivnetFileArtifact(), "") Expect(err).To(MatchError(ContainSubstring(fmt.Sprintf(errorTemplateForStemcell, "1.0def")))) }) + + It("returns an error when multiple stemcell types are found", func() { + fakePivnetDownloader.ReleaseDependenciesReturns([]pivnet.ReleaseDependency{ + createReleaseDependency(789, "1.0", "stemcells-ubuntu-jammy"), + createReleaseDependency(789, "1.0", "stemcells-windows-server"), + }, nil) + + client := download_clients.NewPivnetClient(stdout, stderr, fakePivnetFactory, "", true, "") + _, err := client.GetLatestStemcellForProduct(createPivnetFileArtifact(), "") + Expect(err).To(MatchError(ContainSubstring("could not determine stemcell: multiple stemcell types found: stemcells-ubuntu-jammy, stemcells-windows-server"))) + }) }) }) diff --git a/go.mod b/go.mod index cb081a84..c42439bc 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,7 @@ require ( github.com/pivotal-cf/replicator v0.0.0-20181127185712-7c58987ce14b github.com/pivotal-cf/winfs-injector v0.0.0-20200827170301-91411420d92f github.com/vmware/govmomi v0.46.0 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/oauth2 v0.24.0 google.golang.org/api v0.205.0 gopkg.in/go-playground/validator.v9 v9.31.0 diff --git a/go.sum b/go.sum index a743f956..6bd4f7ce 100644 --- a/go.sum +++ b/go.sum @@ -466,6 +466,8 @@ golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=