Skip to content

Commit f28a479

Browse files
authored
✨ refactor garbage collection to use GarbageCollectAssets API and update related tests (#1470)
1 parent a8f2da5 commit f28a479

12 files changed

Lines changed: 73 additions & 103 deletions

File tree

cmd/mondoo-operator/garbage_collect/cmd.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func init() {
9090
}
9191

9292
func GarbageCollectCmd(ctx context.Context, client mondooclient.MondooClient, spaceMrn, platformRuntime, olderThan, managedBy string, logger logr.Logger) error {
93-
req := &mondooclient.DeleteAssetsRequest{
93+
req := &mondooclient.GarbageCollectAssetsRequest{
9494
SpaceMrn: spaceMrn,
9595
ManagedBy: managedBy,
9696
}
@@ -118,8 +118,7 @@ func GarbageCollectCmd(ctx context.Context, client mondooclient.MondooClient, sp
118118
}
119119
}
120120

121-
resp, err := client.DeleteAssets(ctx, req)
122-
if err != nil {
121+
if err := client.GarbageCollectAssets(ctx, req); err != nil {
123122
if errors.Is(err, context.DeadlineExceeded) {
124123
logger.Error(err, "failed to receive a response before timeout was exceeded")
125124
} else {
@@ -128,13 +127,7 @@ func GarbageCollectCmd(ctx context.Context, client mondooclient.MondooClient, sp
128127
return err
129128
}
130129

131-
if len(resp.AssetMrns) > 0 {
132-
logger.Info("Deleted assets", "count", len(resp.AssetMrns))
133-
}
134-
if len(resp.Errors) > 0 {
135-
logger.Info("DeleteAssets completed with errors", "errors", resp.Errors)
136-
}
137-
130+
logger.Info("Garbage collection complete")
138131
return nil
139132
}
140133

controllers/k8s_scan/deployment_handler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ func (n *DeploymentHandler) garbageCollectIfNeeded(ctx context.Context, clusterU
610610

611611
// performGarbageCollection calls the Mondoo API to delete stale K8s resource scan assets.
612612
func (n *DeploymentHandler) performGarbageCollection(ctx context.Context, managedBy string) error {
613-
req := &mondooclient.DeleteAssetsRequest{
613+
req := &mondooclient.GarbageCollectAssetsRequest{
614614
ManagedBy: managedBy,
615615
PlatformRuntime: "k8s-cluster",
616616
DateFilter: &mondooclient.DateFilter{
@@ -620,7 +620,7 @@ func (n *DeploymentHandler) performGarbageCollection(ctx context.Context, manage
620620
},
621621
}
622622

623-
if err := mondoo.DeleteStaleAssets(ctx, n.KubeClient, n.Mondoo, n.MondooOperatorConfig, n.MondooClientBuilder, req, logger); err != nil {
623+
if err := mondoo.GarbageCollectAssets(ctx, n.KubeClient, n.Mondoo, n.MondooOperatorConfig, n.MondooClientBuilder, req, logger); err != nil {
624624
return err
625625
}
626626

controllers/k8s_scan/deployment_handler_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,7 +1578,7 @@ func TestExternalClusterNaming(t *testing.T) {
15781578

15791579
func (s *DeploymentHandlerSuite) TestGarbageCollection_RunsAfterSuccessfulScan() {
15801580
gcCalled := false
1581-
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, req *mondooclient.DeleteAssetsRequest) error {
1581+
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, req *mondooclient.GarbageCollectAssetsRequest) error {
15821582
gcCalled = true
15831583
s.Equal("k8s-cluster", req.PlatformRuntime)
15841584
s.Contains(req.ManagedBy, "mondoo-operator-")
@@ -1609,13 +1609,13 @@ func (s *DeploymentHandlerSuite) TestGarbageCollection_RunsAfterSuccessfulScan()
16091609
s.NoError(err)
16101610
s.True(result.IsZero())
16111611

1612-
s.True(gcCalled, "DeleteAssets should have been called")
1612+
s.True(gcCalled, "GarbageCollectAssets should have been called")
16131613
s.NotNil(d.Mondoo.Status.LastK8sResourceGarbageCollectionTime, "GC timestamp should be set in status")
16141614
}
16151615

16161616
func (s *DeploymentHandlerSuite) TestGarbageCollection_SkipsWhenAlreadyRun() {
16171617
gcCalled := false
1618-
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, opts *mondooclient.DeleteAssetsRequest) error {
1618+
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, opts *mondooclient.GarbageCollectAssetsRequest) error {
16191619
gcCalled = true
16201620
return nil
16211621
})
@@ -1644,11 +1644,11 @@ func (s *DeploymentHandlerSuite) TestGarbageCollection_SkipsWhenAlreadyRun() {
16441644
s.NoError(err)
16451645
s.True(result.IsZero())
16461646

1647-
s.False(gcCalled, "DeleteAssets should NOT have been called")
1647+
s.False(gcCalled, "GarbageCollectAssets should NOT have been called")
16481648
}
16491649

16501650
func (s *DeploymentHandlerSuite) TestGarbageCollection_FailureStillUpdatesTimestamp() {
1651-
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, opts *mondooclient.DeleteAssetsRequest) error {
1651+
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, opts *mondooclient.GarbageCollectAssetsRequest) error {
16521652
return fmt.Errorf("API error")
16531653
})
16541654
s.NoError(d.KubeClient.Create(s.ctx, &s.auditConfig))
@@ -1677,8 +1677,8 @@ func (s *DeploymentHandlerSuite) TestGarbageCollection_FailureStillUpdatesTimest
16771677
}
16781678

16791679
// createDeploymentHandlerWithGCMock creates a DeploymentHandler with a mock MondooClientBuilder
1680-
// that captures calls to DeleteAssets.
1681-
func (s *DeploymentHandlerSuite) createDeploymentHandlerWithGCMock(gcFunc func(context.Context, *mondooclient.DeleteAssetsRequest) error) DeploymentHandler {
1680+
// that captures calls to GarbageCollectAssets.
1681+
func (s *DeploymentHandlerSuite) createDeploymentHandlerWithGCMock(gcFunc func(context.Context, *mondooclient.GarbageCollectAssetsRequest) error) DeploymentHandler {
16821682
// Create a mock credentials secret so GC can read it
16831683
key := credentials.MondooServiceAccount(s.T())
16841684
mockSA := mondooclient.ServiceAccountCredentials{
@@ -1713,14 +1713,14 @@ func (s *DeploymentHandlerSuite) createDeploymentHandlerWithGCMock(gcFunc func(c
17131713
// fakeMondooClient implements just enough of MondooClient to test GC
17141714
type fakeMondooClient struct {
17151715
mondooclient.MondooClient
1716-
gcFunc func(context.Context, *mondooclient.DeleteAssetsRequest) error
1716+
gcFunc func(context.Context, *mondooclient.GarbageCollectAssetsRequest) error
17171717
}
17181718

1719-
func (f *fakeMondooClient) DeleteAssets(ctx context.Context, req *mondooclient.DeleteAssetsRequest) (*mondooclient.DeleteAssetsConfirmation, error) {
1719+
func (f *fakeMondooClient) GarbageCollectAssets(ctx context.Context, req *mondooclient.GarbageCollectAssetsRequest) error {
17201720
if f.gcFunc != nil {
1721-
return &mondooclient.DeleteAssetsConfirmation{}, f.gcFunc(ctx, req)
1721+
return f.gcFunc(ctx, req)
17221722
}
1723-
return &mondooclient.DeleteAssetsConfirmation{}, nil
1723+
return nil
17241724
}
17251725

17261726
func TestDeploymentHandlerSuite(t *testing.T) {

controllers/nodes/deployment_handler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ func (n *DeploymentHandler) performGarbageCollection(ctx context.Context, manage
438438
// Node assets are scanned via the filesystem/OS provider and have no PlatformRuntime set
439439
// (unlike k8s resource assets which have PlatformRuntime "k8s-cluster").
440440
// Omitting PlatformRuntime so the filter matches node assets.
441-
req := &mondooclient.DeleteAssetsRequest{
441+
req := &mondooclient.GarbageCollectAssetsRequest{
442442
ManagedBy: managedBy,
443443
DateFilter: &mondooclient.DateFilter{
444444
Timestamp: time.Now().Add(-mondoo.GCOlderThan(n.Mondoo.Spec.Nodes.Schedule)).Format(time.RFC3339),
@@ -447,7 +447,7 @@ func (n *DeploymentHandler) performGarbageCollection(ctx context.Context, manage
447447
},
448448
}
449449

450-
if err := mondoo.DeleteStaleAssets(ctx, n.KubeClient, n.Mondoo, n.MondooOperatorConfig, n.MondooClientBuilder, req, logger); err != nil {
450+
if err := mondoo.GarbageCollectAssets(ctx, n.KubeClient, n.Mondoo, n.MondooOperatorConfig, n.MondooClientBuilder, req, logger); err != nil {
451451
return err
452452
}
453453

controllers/nodes/deployment_handler_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ func (s *DeploymentHandlerSuite) TestReconcile_Deployment_CustomInterval() {
772772
func (s *DeploymentHandlerSuite) TestGarbageCollection_RunsAfterSuccessfulScan() {
773773
s.seedNodes()
774774
gcCalled := false
775-
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, req *mondooclient.DeleteAssetsRequest) error {
775+
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, req *mondooclient.GarbageCollectAssetsRequest) error {
776776
gcCalled = true
777777
s.Contains(req.ManagedBy, "mondoo-operator-")
778778
s.NotNil(req.DateFilter)
@@ -806,14 +806,14 @@ func (s *DeploymentHandlerSuite) TestGarbageCollection_RunsAfterSuccessfulScan()
806806
s.NoError(err)
807807
s.True(result.IsZero())
808808

809-
s.True(gcCalled, "DeleteAssets should have been called")
809+
s.True(gcCalled, "GarbageCollectAssets should have been called")
810810
s.NotNil(d.Mondoo.Status.LastNodeScanGarbageCollectionTime, "GC timestamp should be set in status")
811811
}
812812

813813
func (s *DeploymentHandlerSuite) TestGarbageCollection_SkipsWhenAlreadyRun() {
814814
s.seedNodes()
815815
gcCalled := false
816-
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, opts *mondooclient.DeleteAssetsRequest) error {
816+
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, opts *mondooclient.GarbageCollectAssetsRequest) error {
817817
gcCalled = true
818818
return nil
819819
})
@@ -846,12 +846,12 @@ func (s *DeploymentHandlerSuite) TestGarbageCollection_SkipsWhenAlreadyRun() {
846846
s.NoError(err)
847847
s.True(result.IsZero())
848848

849-
s.False(gcCalled, "DeleteAssets should NOT have been called")
849+
s.False(gcCalled, "GarbageCollectAssets should NOT have been called")
850850
}
851851

852852
func (s *DeploymentHandlerSuite) TestGarbageCollection_FailureStillUpdatesTimestamp() {
853853
s.seedNodes()
854-
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, opts *mondooclient.DeleteAssetsRequest) error {
854+
d := s.createDeploymentHandlerWithGCMock(func(ctx context.Context, opts *mondooclient.GarbageCollectAssetsRequest) error {
855855
return fmt.Errorf("API error")
856856
})
857857
s.NoError(d.KubeClient.Create(s.ctx, &s.auditConfig))
@@ -893,8 +893,8 @@ func (s *DeploymentHandlerSuite) createDeploymentHandler() DeploymentHandler {
893893
}
894894

895895
// createDeploymentHandlerWithGCMock creates a DeploymentHandler with a mock MondooClientBuilder
896-
// that captures calls to DeleteAssets.
897-
func (s *DeploymentHandlerSuite) createDeploymentHandlerWithGCMock(gcFunc func(context.Context, *mondooclient.DeleteAssetsRequest) error) DeploymentHandler {
896+
// that captures calls to GarbageCollectAssets.
897+
func (s *DeploymentHandlerSuite) createDeploymentHandlerWithGCMock(gcFunc func(context.Context, *mondooclient.GarbageCollectAssetsRequest) error) DeploymentHandler {
898898
// Create a mock credentials secret so GC can read it
899899
key := generateTestPrivateKey(s.T())
900900
mockSA := mondooclient.ServiceAccountCredentials{
@@ -929,14 +929,14 @@ func (s *DeploymentHandlerSuite) createDeploymentHandlerWithGCMock(gcFunc func(c
929929
// fakeMondooClient implements just enough of MondooClient to test GC
930930
type fakeMondooClient struct {
931931
mondooclient.MondooClient
932-
gcFunc func(context.Context, *mondooclient.DeleteAssetsRequest) error
932+
gcFunc func(context.Context, *mondooclient.GarbageCollectAssetsRequest) error
933933
}
934934

935-
func (f *fakeMondooClient) DeleteAssets(ctx context.Context, req *mondooclient.DeleteAssetsRequest) (*mondooclient.DeleteAssetsConfirmation, error) {
935+
func (f *fakeMondooClient) GarbageCollectAssets(ctx context.Context, req *mondooclient.GarbageCollectAssetsRequest) error {
936936
if f.gcFunc != nil {
937-
return &mondooclient.DeleteAssetsConfirmation{}, f.gcFunc(ctx, req)
937+
return f.gcFunc(ctx, req)
938938
}
939-
return &mondooclient.DeleteAssetsConfirmation{}, nil
939+
return nil
940940
}
941941

942942
// generateTestPrivateKey generates an ECDSA private key and returns its PEM-encoded string.

pkg/client/mondooclient/client.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const (
1919
IntegrationRegisterEndpoint = "/IntegrationsManager/Register"
2020
IntegrationCheckInEndpoint = "/IntegrationsManager/CheckIn"
2121
IntegrationReportStatusEndpoint = "/IntegrationsManager/ReportStatus"
22-
DeleteAssetsEndpoint = "/AssetStore/DeleteAssets"
22+
GarbageCollectAssetsEndpoint = "/PolicyResolver/PurgeAssets"
2323
)
2424

2525
type MondooClientOptions struct {
@@ -150,23 +150,18 @@ func (s *mondooClient) IntegrationReportStatus(ctx context.Context, in *ReportSt
150150
return nil
151151
}
152152

153-
func (s *mondooClient) DeleteAssets(ctx context.Context, req *DeleteAssetsRequest) (*DeleteAssetsConfirmation, error) {
154-
url := s.ApiEndpoint + DeleteAssetsEndpoint
153+
func (s *mondooClient) GarbageCollectAssets(ctx context.Context, req *GarbageCollectAssetsRequest) error {
154+
url := s.ApiEndpoint + GarbageCollectAssetsEndpoint
155155

156156
reqBodyBytes, err := json.Marshal(req)
157157
if err != nil {
158-
return nil, fmt.Errorf("failed to marshal request: %v", err)
158+
return fmt.Errorf("failed to marshal request: %v", err)
159159
}
160160

161-
respBodyBytes, err := common.Request(ctx, s.httpClient, url, s.Token, reqBodyBytes)
161+
_, err = common.Request(ctx, s.httpClient, url, s.Token, reqBodyBytes)
162162
if err != nil {
163-
return nil, fmt.Errorf("failed to make delete assets request: %v", err)
164-
}
165-
166-
out := &DeleteAssetsConfirmation{}
167-
if err = json.Unmarshal(respBodyBytes, out); err != nil {
168-
return nil, fmt.Errorf("failed to unmarshal response: %v", err)
163+
return fmt.Errorf("failed to make garbage collect assets request: %v", err)
169164
}
170165

171-
return out, nil
166+
return nil
172167
}

pkg/client/mondooclient/mock/client_generated.go

Lines changed: 14 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/client/mondooclient/types.go

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ type MondooClient interface {
1919
IntegrationCheckIn(context.Context, *IntegrationCheckInInput) (*IntegrationCheckInOutput, error)
2020
IntegrationReportStatus(context.Context, *ReportStatusRequest) error
2121

22-
DeleteAssets(context.Context, *DeleteAssetsRequest) (*DeleteAssetsConfirmation, error)
22+
GarbageCollectAssets(context.Context, *GarbageCollectAssetsRequest) error
2323
}
2424

2525
// ExchangeRegistrationTokenInput is used for converting a JWT to a Mondoo serivce account
@@ -116,14 +116,14 @@ const (
116116
MessageStatus_MESSAGE_INFO MessageStatus = 3
117117
)
118118

119-
// DeleteAssetsRequest matches the server-side DeleteAssetsRequest proto.
120-
type DeleteAssetsRequest struct {
121-
SpaceMrn string `json:"spaceMrn,omitempty"`
122-
AssetMrns []string `json:"asset_mrns,omitempty"`
123-
DeleteAll bool `json:"delete_all,omitempty"`
124-
DateFilter *DateFilter `json:"date_filter,omitempty"`
125-
ManagedBy string `json:"managed_by,omitempty"`
126-
PlatformRuntime string `json:"platform_runtime,omitempty"`
119+
// GarbageCollectAssetsRequest matches the server-side PurgeAssetsRequest proto
120+
// on the PolicyResolver service (/PolicyResolver/PurgeAssets).
121+
type GarbageCollectAssetsRequest struct {
122+
SpaceMrn string `json:"spaceMrn,omitempty"`
123+
DateFilter *DateFilter `json:"date_filter,omitempty"`
124+
ManagedBy string `json:"managed_by,omitempty"`
125+
PlatformRuntime string `json:"platform_runtime,omitempty"` // optional filter (k8s-cluster, docker-image, etc.)
126+
Labels map[string]string `json:"labels,omitempty"`
127127
}
128128

129129
type DateFilter struct {
@@ -145,9 +145,3 @@ const (
145145
DateFilterField_FILTER_LAST_UPDATED DateFilterField = 0
146146
DateFilterField_FILTER_CREATED DateFilterField = 1
147147
)
148-
149-
// DeleteAssetsConfirmation is the response from the DeleteAssets API.
150-
type DeleteAssetsConfirmation struct {
151-
AssetMrns []string `json:"asset_mrns,omitempty"`
152-
Errors map[string]string `json:"errors,omitempty"`
153-
}

0 commit comments

Comments
 (0)