From 3eb3945185c636415ea3452aaebfd8e844d0e5c4 Mon Sep 17 00:00:00 2001 From: Ryan Hall Date: Mon, 17 Jun 2024 16:51:32 -0400 Subject: [PATCH] [feat]: Add Auto-Accept EULA functionality to OM (#652) feat: Adds Auto-Accept EULA functionality when Downloading products. Because of the great migration from TanzuNet to RMT, not all EULA data will potentially transfer, so this version of OM added the `AcceptEula` pivnet_client functionality to the `PivnetDownloader` interface. This allows the Pivnet client to Auto-Accept the EULA for the product it downloads, while also allowing the mock to be generated for accurate testing. Co-authored-by: Ryan Hall Co-authored-by: Janice Bailey --- configtemplate/metadata/pivnet_test.go | 3 + depstability/records/depnames-7.11.0.txt | 1 + .../fakes/pivnet_downloader_service.go | 75 +++++++++++++++++++ download_clients/pivnet_client.go | 11 ++- download_clients/pivnet_client_test.go | 17 ++++- 5 files changed, 103 insertions(+), 4 deletions(-) diff --git a/configtemplate/metadata/pivnet_test.go b/configtemplate/metadata/pivnet_test.go index b08803302..e18dab560 100644 --- a/configtemplate/metadata/pivnet_test.go +++ b/configtemplate/metadata/pivnet_test.go @@ -17,6 +17,9 @@ var _ = Describe("Pivnet Client", func() { server.RouteToHandler("GET", "/api/v2/products/example-product/releases/1", ghttp.RespondWith(http.StatusOK, `{"id":1}`), ) + server.RouteToHandler("POST", "/api/v2/products/example-product/releases/1/pivnet_resource_eula_acceptance", + ghttp.RespondWith(http.StatusOK, `{}`), + ) server.RouteToHandler("GET", "/api/v2/products/example-product/releases/1/file_groups", ghttp.RespondWith(http.StatusOK, `{}`), ) diff --git a/depstability/records/depnames-7.11.0.txt b/depstability/records/depnames-7.11.0.txt index 338b370ff..c4054e167 100644 --- a/depstability/records/depnames-7.11.0.txt +++ b/depstability/records/depnames-7.11.0.txt @@ -73,6 +73,7 @@ github.com/go-ole/go-ole github.com/go-playground/locales github.com/go-playground/universal-translator github.com/go-task/slim-sprig +github.com/go-task/slim-sprig/v3 github.com/gofrs/uuid github.com/golang-jwt/jwt/v4 github.com/golang/glog diff --git a/download_clients/fakes/pivnet_downloader_service.go b/download_clients/fakes/pivnet_downloader_service.go index d408fe4b1..4f0d1505f 100644 --- a/download_clients/fakes/pivnet_downloader_service.go +++ b/download_clients/fakes/pivnet_downloader_service.go @@ -11,6 +11,18 @@ import ( ) type PivnetDownloader struct { + AcceptEULAStub func(string, int) error + acceptEULAMutex sync.RWMutex + acceptEULAArgsForCall []struct { + arg1 string + arg2 int + } + acceptEULAReturns struct { + result1 error + } + acceptEULAReturnsOnCall map[int]struct { + result1 error + } DownloadProductFileStub func(*download.FileInfo, string, int, int, io.Writer) error downloadProductFileMutex sync.RWMutex downloadProductFileArgsForCall []struct { @@ -86,6 +98,67 @@ type PivnetDownloader struct { invocationsMutex sync.RWMutex } +func (fake *PivnetDownloader) AcceptEULA(arg1 string, arg2 int) error { + fake.acceptEULAMutex.Lock() + ret, specificReturn := fake.acceptEULAReturnsOnCall[len(fake.acceptEULAArgsForCall)] + fake.acceptEULAArgsForCall = append(fake.acceptEULAArgsForCall, struct { + arg1 string + arg2 int + }{arg1, arg2}) + fake.recordInvocation("AcceptEULA", []interface{}{arg1, arg2}) + fake.acceptEULAMutex.Unlock() + if fake.AcceptEULAStub != nil { + return fake.AcceptEULAStub(arg1, arg2) + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.acceptEULAReturns + return fakeReturns.result1 +} + +func (fake *PivnetDownloader) AcceptEULACallCount() int { + fake.acceptEULAMutex.RLock() + defer fake.acceptEULAMutex.RUnlock() + return len(fake.acceptEULAArgsForCall) +} + +func (fake *PivnetDownloader) AcceptEULACalls(stub func(string, int) error) { + fake.acceptEULAMutex.Lock() + defer fake.acceptEULAMutex.Unlock() + fake.AcceptEULAStub = stub +} + +func (fake *PivnetDownloader) AcceptEULAArgsForCall(i int) (string, int) { + fake.acceptEULAMutex.RLock() + defer fake.acceptEULAMutex.RUnlock() + argsForCall := fake.acceptEULAArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *PivnetDownloader) AcceptEULAReturns(result1 error) { + fake.acceptEULAMutex.Lock() + defer fake.acceptEULAMutex.Unlock() + fake.AcceptEULAStub = nil + fake.acceptEULAReturns = struct { + result1 error + }{result1} +} + +func (fake *PivnetDownloader) AcceptEULAReturnsOnCall(i int, result1 error) { + fake.acceptEULAMutex.Lock() + defer fake.acceptEULAMutex.Unlock() + fake.AcceptEULAStub = nil + if fake.acceptEULAReturnsOnCall == nil { + fake.acceptEULAReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.acceptEULAReturnsOnCall[i] = struct { + result1 error + }{result1} +} + func (fake *PivnetDownloader) DownloadProductFile(arg1 *download.FileInfo, arg2 string, arg3 int, arg4 int, arg5 io.Writer) error { fake.downloadProductFileMutex.Lock() ret, specificReturn := fake.downloadProductFileReturnsOnCall[len(fake.downloadProductFileArgsForCall)] @@ -409,6 +482,8 @@ func (fake *PivnetDownloader) ReleasesForProductSlugReturnsOnCall(i int, result1 func (fake *PivnetDownloader) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() + fake.acceptEULAMutex.RLock() + defer fake.acceptEULAMutex.RUnlock() fake.downloadProductFileMutex.RLock() defer fake.downloadProductFileMutex.RUnlock() fake.productFilesForReleaseMutex.RLock() diff --git a/download_clients/pivnet_client.go b/download_clients/pivnet_client.go index 5a98b6840..cb2df1d9c 100644 --- a/download_clients/pivnet_client.go +++ b/download_clients/pivnet_client.go @@ -2,8 +2,6 @@ package download_clients import ( "fmt" - "github.com/pivotal-cf/go-pivnet/v6/logshim" - "github.com/pivotal-cf/pivnet-cli/v2/filter" "io" "log" "os" @@ -11,6 +9,9 @@ import ( "strconv" "strings" + "github.com/pivotal-cf/go-pivnet/v6/logshim" + "github.com/pivotal-cf/pivnet-cli/v2/filter" + "github.com/pivotal-cf/go-pivnet/v6" "github.com/pivotal-cf/go-pivnet/v6/download" pivnetlog "github.com/pivotal-cf/go-pivnet/v6/logger" @@ -24,6 +25,7 @@ type PivnetDownloader interface { ProductFilesForRelease(productSlug string, releaseID int) ([]pivnet.ProductFile, error) DownloadProductFile(location *download.FileInfo, productSlug string, releaseID int, productFileID int, progressWriter io.Writer) error ReleaseDependencies(productSlug string, releaseID int) ([]pivnet.ReleaseDependency, error) + AcceptEULA(productSlug string, releaseID int) error } type PivnetFactory func(ts pivnet.AccessTokenService, config pivnet.ClientConfig, logger pivnetlog.Logger) PivnetDownloader @@ -95,6 +97,11 @@ func (p *pivnetClient) GetLatestProductFile(slug, version, glob string) (FileArt return nil, fmt.Errorf("could not fetch the release for %s %s: %s", slug, version, err) } + err = p.downloader.AcceptEULA(slug, release.ID) + if err != nil { + return nil, fmt.Errorf("could not accept EULA for download product file %s at version %s: %s", slug, version, err) + } + // 2. Get filename from pivnet productFiles, err := p.downloader.ProductFilesForRelease(slug, release.ID) if err != nil { diff --git a/download_clients/pivnet_client_test.go b/download_clients/pivnet_client_test.go index f53808524..37708c53d 100644 --- a/download_clients/pivnet_client_test.go +++ b/download_clients/pivnet_client_test.go @@ -4,13 +4,14 @@ import ( "bytes" "errors" "fmt" - "github.com/onsi/gomega/ghttp" - pivnetlog "github.com/pivotal-cf/go-pivnet/v6/logger" "io/ioutil" "log" "net/http" "time" + "github.com/onsi/gomega/ghttp" + pivnetlog "github.com/pivotal-cf/go-pivnet/v6/logger" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/pivotal-cf/go-pivnet/v6" @@ -57,6 +58,10 @@ var _ = Describe("Grabbing Metadata", func() { ghttp.VerifyRequest("GET", "/api/v2/products/pivnet-product/releases/24"), ghttp.RespondWith(http.StatusOK, `{"id":24}`), ), + ghttp.CombineHandlers( + ghttp.VerifyRequest("POST", "/api/v2/products/pivnet-product/releases/24/pivnet_resource_eula_acceptance"), + ghttp.RespondWith(http.StatusOK, ""), + ), ghttp.CombineHandlers( ghttp.VerifyRequest("GET", "/api/v2/products/pivnet-product/releases/24/product_files"), ghttp.RespondWith(http.StatusOK, fmt.Sprintf(`{ @@ -189,6 +194,14 @@ var _ = Describe("PivnetClient", func() { Expect(err).To(MatchError(ContainSubstring("could not fetch the release for someslug"))) }) + It("returns an error if it could not accept the EULA", func() { + fakePivnetDownloader.AcceptEULAReturns(errors.New("some error")) + + client := download_clients.NewPivnetClient(stdout, stderr, fakePivnetFactory, "", true, "") + _, err := client.GetLatestProductFile("someslug", "1.0.0", "*.zip") + Expect(err).To(MatchError(ContainSubstring("could not accept EULA"))) + }) + It("returns an error if product files are not available for a slug", func() { fakePivnetDownloader.ReleaseForVersionReturns(createRelease("1.0.0"), nil) fakePivnetDownloader.ProductFilesForReleaseReturns([]pivnet.ProductFile{}, errors.New("some error"))