diff --git a/.secrets.baseline b/.secrets.baseline index 9b2ff95ee..b7e0c3db6 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -376,21 +376,21 @@ "filename": "pkg/client/fleetmanager/mocks/client_moq.go", "hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c", "is_verified": false, - "line_number": 584 + "line_number": 646 }, { "type": "Secret Keyword", "filename": "pkg/client/fleetmanager/mocks/client_moq.go", "hashed_secret": "0ff50155b4f57adeccae93f27dc23efe2a8b7824", "is_verified": false, - "line_number": 585 + "line_number": 647 }, { "type": "Secret Keyword", "filename": "pkg/client/fleetmanager/mocks/client_moq.go", "hashed_secret": "5ce1b8d4fb9dae5c02b2017e39e7267a21cea37f", "is_verified": false, - "line_number": 594 + "line_number": 656 } ], "pkg/client/iam/client_moq.go": [ @@ -586,5 +586,5 @@ } ] }, - "generated_at": "2024-02-05T19:02:34Z" + "generated_at": "2024-02-15T11:09:43Z" } diff --git a/e2e/e2e_central_traits_test.go b/e2e/e2e_central_traits_test.go new file mode 100644 index 000000000..07af1bcde --- /dev/null +++ b/e2e/e2e_central_traits_test.go @@ -0,0 +1,102 @@ +package e2e + +import ( + "context" + "net/http" + "os" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/stackrox/acs-fleet-manager/internal/dinosaur/pkg/api/admin/private" + "github.com/stackrox/acs-fleet-manager/pkg/client/fleetmanager" + fmImpl "github.com/stackrox/acs-fleet-manager/pkg/client/fleetmanager/impl" +) + +var _ = Describe("central traits", Ordered, func() { + + var client *fleetmanager.Client + var adminAPI fleetmanager.AdminAPI + var notes []string + var ctx = context.Background() + + BeforeEach(func() { + SkipIf(!runCentralTests, "Skipping Central tests") + Expect(restoreDefaultGitopsConfig()).To(Succeed()) + + option := fmImpl.OptionFromEnv() + auth, err := fmImpl.NewStaticAuth(context.Background(), fmImpl.StaticOption{StaticToken: option.Static.StaticToken}) + Expect(err).ToNot(HaveOccurred()) + client, err = fmImpl.NewClient(fleetManagerEndpoint, auth) + Expect(err).ToNot(HaveOccurred()) + + adminStaticToken := os.Getenv("STATIC_TOKEN_ADMIN") + adminAuth, err := fmImpl.NewStaticAuth(context.Background(), fmImpl.StaticOption{StaticToken: adminStaticToken}) + Expect(err).ToNot(HaveOccurred()) + adminClient, err := fmImpl.NewClient(fleetManagerEndpoint, adminAuth) + Expect(err).ToNot(HaveOccurred()) + adminAPI = adminClient.AdminAPI() + + GinkgoWriter.Printf("Current time: %s\n", time.Now().String()) + printNotes(notes) + }) + + It("should manage traits", func() { + central, _, err := adminAPI.CreateCentral(ctx, true, private.CentralRequestPayload{ + CloudProvider: dpCloudProvider, + MultiAz: true, + Name: newCentralName(), + Region: dpRegion, + }) + Expect(err).Should(Succeed()) + id := central.Id + + Eventually(assertCentralRequestProvisioning(ctx, client, id)). + WithTimeout(waitTimeout). + WithPolling(defaultPolling). + Should(Succeed()) + + defer adminAPI.DeleteDbCentralById(ctx, id) + + traits, _, err := adminAPI.GetCentralTraits(ctx, id) + Expect(err).ToNot(HaveOccurred(), "no error on no traits") + Expect(traits).To(BeEmpty(), "no traits yet") + + _, err = adminAPI.PutCentralTrait(ctx, id, "test-trait") + Expect(err).ToNot(HaveOccurred(), "no error on adding test-trait") + + traits, _, err = adminAPI.GetCentralTraits(ctx, id) + Expect(err).ToNot(HaveOccurred(), "no error on having traits") + Expect(traits).To(BeEquivalentTo([]string{"test-trait"}), "test-trait should be found") + + _, err = adminAPI.PutCentralTrait(ctx, id, "test-trait-1") + Expect(err).ToNot(HaveOccurred(), "no error on adding test-trait-1") + + _, err = adminAPI.PutCentralTrait(ctx, id, "test-trait-1") + Expect(err).ToNot(HaveOccurred(), "no error on adding test-trait-1 twice") + + traits, _, err = adminAPI.GetCentralTraits(ctx, id) + Expect(err).ToNot(HaveOccurred(), "no error on having multiple traits") + Expect(traits).To(BeEquivalentTo([]string{"test-trait", "test-trait-1"}), "should have only two traits") + + _, err = adminAPI.GetCentralTrait(ctx, id, "test-trait") + Expect(err).ToNot(HaveOccurred(), "no error on checking for existing trait") + + resp, err := adminAPI.GetCentralTrait(ctx, id, "test-trait-2") + Expect(err).To(HaveOccurred(), "error on checking for non-existing trait") + if Expect(resp).NotTo(BeNil()) { + Expect(resp.StatusCode == http.StatusNotFound).To(BeTrue()) + } + + _, err = adminAPI.DeleteCentralTrait(ctx, id, "test-trait") + Expect(err).ToNot(HaveOccurred(), "no error on deleting test-trait") + + _, err = adminAPI.DeleteCentralTrait(ctx, id, "test-trait") + Expect(err).ToNot(HaveOccurred(), "no error on deleting non-existing trait") + + traits, _, err = adminAPI.GetCentralTraits(ctx, id) + Expect(err).ToNot(HaveOccurred(), "no error on retreiving traits") + Expect(traits).To(BeEquivalentTo([]string{"test-trait-1"}), "should have only one trait now") + }) +}) diff --git a/pkg/client/fleetmanager/client.go b/pkg/client/fleetmanager/client.go index f50ee9ef7..273cc60fb 100644 --- a/pkg/client/fleetmanager/client.go +++ b/pkg/client/fleetmanager/client.go @@ -34,6 +34,11 @@ type AdminAPI interface { DeleteDbCentralById(ctx context.Context, id string) (*http.Response, error) CentralRotateSecrets(ctx context.Context, id string, centralRotateSecretsRequest admin.CentralRotateSecretsRequest) (*http.Response, error) UpdateCentralNameById(ctx context.Context, id string, centralUpdateNameRequest admin.CentralUpdateNameRequest) (admin.Central, *http.Response, error) + + GetCentralTraits(ctx context.Context, id string) ([]string, *http.Response, error) + GetCentralTrait(ctx context.Context, id string, trait string) (*http.Response, error) + PutCentralTrait(ctx context.Context, id string, trait string) (*http.Response, error) + DeleteCentralTrait(ctx context.Context, id string, trait string) (*http.Response, error) } // Client is a helper struct that wraps around the API clients generated from diff --git a/pkg/client/fleetmanager/mocks/client_moq.go b/pkg/client/fleetmanager/mocks/client_moq.go index a867684f3..901487970 100644 --- a/pkg/client/fleetmanager/mocks/client_moq.go +++ b/pkg/client/fleetmanager/mocks/client_moq.go @@ -497,12 +497,24 @@ var _ fleetmanager.AdminAPI = &AdminAPIMock{} // CreateCentralFunc: func(ctx context.Context, async bool, centralRequestPayload admin.CentralRequestPayload) (admin.CentralRequest, *http.Response, error) { // panic("mock out the CreateCentral method") // }, +// DeleteCentralTraitFunc: func(ctx context.Context, id string, trait string) (*http.Response, error) { +// panic("mock out the DeleteCentralTrait method") +// }, // DeleteDbCentralByIdFunc: func(ctx context.Context, id string) (*http.Response, error) { // panic("mock out the DeleteDbCentralById method") // }, +// GetCentralTraitFunc: func(ctx context.Context, id string, trait string) (*http.Response, error) { +// panic("mock out the GetCentralTrait method") +// }, +// GetCentralTraitsFunc: func(ctx context.Context, id string) ([]string, *http.Response, error) { +// panic("mock out the GetCentralTraits method") +// }, // GetCentralsFunc: func(ctx context.Context, localVarOptionals *admin.GetCentralsOpts) (admin.CentralList, *http.Response, error) { // panic("mock out the GetCentrals method") // }, +// PutCentralTraitFunc: func(ctx context.Context, id string, trait string) (*http.Response, error) { +// panic("mock out the PutCentralTrait method") +// }, // UpdateCentralNameByIdFunc: func(ctx context.Context, id string, centralUpdateNameRequest admin.CentralUpdateNameRequest) (admin.Central, *http.Response, error) { // panic("mock out the UpdateCentralNameById method") // }, @@ -519,12 +531,24 @@ type AdminAPIMock struct { // CreateCentralFunc mocks the CreateCentral method. CreateCentralFunc func(ctx context.Context, async bool, centralRequestPayload admin.CentralRequestPayload) (admin.CentralRequest, *http.Response, error) + // DeleteCentralTraitFunc mocks the DeleteCentralTrait method. + DeleteCentralTraitFunc func(ctx context.Context, id string, trait string) (*http.Response, error) + // DeleteDbCentralByIdFunc mocks the DeleteDbCentralById method. DeleteDbCentralByIdFunc func(ctx context.Context, id string) (*http.Response, error) + // GetCentralTraitFunc mocks the GetCentralTrait method. + GetCentralTraitFunc func(ctx context.Context, id string, trait string) (*http.Response, error) + + // GetCentralTraitsFunc mocks the GetCentralTraits method. + GetCentralTraitsFunc func(ctx context.Context, id string) ([]string, *http.Response, error) + // GetCentralsFunc mocks the GetCentrals method. GetCentralsFunc func(ctx context.Context, localVarOptionals *admin.GetCentralsOpts) (admin.CentralList, *http.Response, error) + // PutCentralTraitFunc mocks the PutCentralTrait method. + PutCentralTraitFunc func(ctx context.Context, id string, trait string) (*http.Response, error) + // UpdateCentralNameByIdFunc mocks the UpdateCentralNameById method. UpdateCentralNameByIdFunc func(ctx context.Context, id string, centralUpdateNameRequest admin.CentralUpdateNameRequest) (admin.Central, *http.Response, error) @@ -548,6 +572,15 @@ type AdminAPIMock struct { // CentralRequestPayload is the centralRequestPayload argument value. CentralRequestPayload admin.CentralRequestPayload } + // DeleteCentralTrait holds details about calls to the DeleteCentralTrait method. + DeleteCentralTrait []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // ID is the id argument value. + ID string + // Trait is the trait argument value. + Trait string + } // DeleteDbCentralById holds details about calls to the DeleteDbCentralById method. DeleteDbCentralById []struct { // Ctx is the ctx argument value. @@ -555,6 +588,22 @@ type AdminAPIMock struct { // ID is the id argument value. ID string } + // GetCentralTrait holds details about calls to the GetCentralTrait method. + GetCentralTrait []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // ID is the id argument value. + ID string + // Trait is the trait argument value. + Trait string + } + // GetCentralTraits holds details about calls to the GetCentralTraits method. + GetCentralTraits []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // ID is the id argument value. + ID string + } // GetCentrals holds details about calls to the GetCentrals method. GetCentrals []struct { // Ctx is the ctx argument value. @@ -562,6 +611,15 @@ type AdminAPIMock struct { // LocalVarOptionals is the localVarOptionals argument value. LocalVarOptionals *admin.GetCentralsOpts } + // PutCentralTrait holds details about calls to the PutCentralTrait method. + PutCentralTrait []struct { + // Ctx is the ctx argument value. + Ctx context.Context + // ID is the id argument value. + ID string + // Trait is the trait argument value. + Trait string + } // UpdateCentralNameById holds details about calls to the UpdateCentralNameById method. UpdateCentralNameById []struct { // Ctx is the ctx argument value. @@ -574,8 +632,12 @@ type AdminAPIMock struct { } lockCentralRotateSecrets sync.RWMutex lockCreateCentral sync.RWMutex + lockDeleteCentralTrait sync.RWMutex lockDeleteDbCentralById sync.RWMutex + lockGetCentralTrait sync.RWMutex + lockGetCentralTraits sync.RWMutex lockGetCentrals sync.RWMutex + lockPutCentralTrait sync.RWMutex lockUpdateCentralNameById sync.RWMutex } @@ -659,6 +721,46 @@ func (mock *AdminAPIMock) CreateCentralCalls() []struct { return calls } +// DeleteCentralTrait calls DeleteCentralTraitFunc. +func (mock *AdminAPIMock) DeleteCentralTrait(ctx context.Context, id string, trait string) (*http.Response, error) { + if mock.DeleteCentralTraitFunc == nil { + panic("AdminAPIMock.DeleteCentralTraitFunc: method is nil but AdminAPI.DeleteCentralTrait was just called") + } + callInfo := struct { + Ctx context.Context + ID string + Trait string + }{ + Ctx: ctx, + ID: id, + Trait: trait, + } + mock.lockDeleteCentralTrait.Lock() + mock.calls.DeleteCentralTrait = append(mock.calls.DeleteCentralTrait, callInfo) + mock.lockDeleteCentralTrait.Unlock() + return mock.DeleteCentralTraitFunc(ctx, id, trait) +} + +// DeleteCentralTraitCalls gets all the calls that were made to DeleteCentralTrait. +// Check the length with: +// +// len(mockedAdminAPI.DeleteCentralTraitCalls()) +func (mock *AdminAPIMock) DeleteCentralTraitCalls() []struct { + Ctx context.Context + ID string + Trait string +} { + var calls []struct { + Ctx context.Context + ID string + Trait string + } + mock.lockDeleteCentralTrait.RLock() + calls = mock.calls.DeleteCentralTrait + mock.lockDeleteCentralTrait.RUnlock() + return calls +} + // DeleteDbCentralById calls DeleteDbCentralByIdFunc. func (mock *AdminAPIMock) DeleteDbCentralById(ctx context.Context, id string) (*http.Response, error) { if mock.DeleteDbCentralByIdFunc == nil { @@ -695,6 +797,82 @@ func (mock *AdminAPIMock) DeleteDbCentralByIdCalls() []struct { return calls } +// GetCentralTrait calls GetCentralTraitFunc. +func (mock *AdminAPIMock) GetCentralTrait(ctx context.Context, id string, trait string) (*http.Response, error) { + if mock.GetCentralTraitFunc == nil { + panic("AdminAPIMock.GetCentralTraitFunc: method is nil but AdminAPI.GetCentralTrait was just called") + } + callInfo := struct { + Ctx context.Context + ID string + Trait string + }{ + Ctx: ctx, + ID: id, + Trait: trait, + } + mock.lockGetCentralTrait.Lock() + mock.calls.GetCentralTrait = append(mock.calls.GetCentralTrait, callInfo) + mock.lockGetCentralTrait.Unlock() + return mock.GetCentralTraitFunc(ctx, id, trait) +} + +// GetCentralTraitCalls gets all the calls that were made to GetCentralTrait. +// Check the length with: +// +// len(mockedAdminAPI.GetCentralTraitCalls()) +func (mock *AdminAPIMock) GetCentralTraitCalls() []struct { + Ctx context.Context + ID string + Trait string +} { + var calls []struct { + Ctx context.Context + ID string + Trait string + } + mock.lockGetCentralTrait.RLock() + calls = mock.calls.GetCentralTrait + mock.lockGetCentralTrait.RUnlock() + return calls +} + +// GetCentralTraits calls GetCentralTraitsFunc. +func (mock *AdminAPIMock) GetCentralTraits(ctx context.Context, id string) ([]string, *http.Response, error) { + if mock.GetCentralTraitsFunc == nil { + panic("AdminAPIMock.GetCentralTraitsFunc: method is nil but AdminAPI.GetCentralTraits was just called") + } + callInfo := struct { + Ctx context.Context + ID string + }{ + Ctx: ctx, + ID: id, + } + mock.lockGetCentralTraits.Lock() + mock.calls.GetCentralTraits = append(mock.calls.GetCentralTraits, callInfo) + mock.lockGetCentralTraits.Unlock() + return mock.GetCentralTraitsFunc(ctx, id) +} + +// GetCentralTraitsCalls gets all the calls that were made to GetCentralTraits. +// Check the length with: +// +// len(mockedAdminAPI.GetCentralTraitsCalls()) +func (mock *AdminAPIMock) GetCentralTraitsCalls() []struct { + Ctx context.Context + ID string +} { + var calls []struct { + Ctx context.Context + ID string + } + mock.lockGetCentralTraits.RLock() + calls = mock.calls.GetCentralTraits + mock.lockGetCentralTraits.RUnlock() + return calls +} + // GetCentrals calls GetCentralsFunc. func (mock *AdminAPIMock) GetCentrals(ctx context.Context, localVarOptionals *admin.GetCentralsOpts) (admin.CentralList, *http.Response, error) { if mock.GetCentralsFunc == nil { @@ -731,6 +909,46 @@ func (mock *AdminAPIMock) GetCentralsCalls() []struct { return calls } +// PutCentralTrait calls PutCentralTraitFunc. +func (mock *AdminAPIMock) PutCentralTrait(ctx context.Context, id string, trait string) (*http.Response, error) { + if mock.PutCentralTraitFunc == nil { + panic("AdminAPIMock.PutCentralTraitFunc: method is nil but AdminAPI.PutCentralTrait was just called") + } + callInfo := struct { + Ctx context.Context + ID string + Trait string + }{ + Ctx: ctx, + ID: id, + Trait: trait, + } + mock.lockPutCentralTrait.Lock() + mock.calls.PutCentralTrait = append(mock.calls.PutCentralTrait, callInfo) + mock.lockPutCentralTrait.Unlock() + return mock.PutCentralTraitFunc(ctx, id, trait) +} + +// PutCentralTraitCalls gets all the calls that were made to PutCentralTrait. +// Check the length with: +// +// len(mockedAdminAPI.PutCentralTraitCalls()) +func (mock *AdminAPIMock) PutCentralTraitCalls() []struct { + Ctx context.Context + ID string + Trait string +} { + var calls []struct { + Ctx context.Context + ID string + Trait string + } + mock.lockPutCentralTrait.RLock() + calls = mock.calls.PutCentralTrait + mock.lockPutCentralTrait.RUnlock() + return calls +} + // UpdateCentralNameById calls UpdateCentralNameByIdFunc. func (mock *AdminAPIMock) UpdateCentralNameById(ctx context.Context, id string, centralUpdateNameRequest admin.CentralUpdateNameRequest) (admin.Central, *http.Response, error) { if mock.UpdateCentralNameByIdFunc == nil {