Skip to content

Commit 8661e25

Browse files
committed
fix(scanning): surface invalid label selectors
1 parent a1aa521 commit 8661e25

8 files changed

Lines changed: 151 additions & 2 deletions

File tree

controllers/container_image/conditions.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package container_image
55

66
import (
7+
"errors"
8+
79
"go.mondoo.com/mondoo-operator/api/v1alpha2"
810
"go.mondoo.com/mondoo-operator/pkg/utils/k8s"
911
"go.mondoo.com/mondoo-operator/pkg/utils/mondoo"
@@ -53,3 +55,21 @@ func updateImageScanningConditions(config *v1alpha2.MondooAuditConfig, degradedS
5355
config.Status.Conditions = mondoo.SetMondooAuditCondition(
5456
config.Status.Conditions, v1alpha2.K8sContainerImageScanningDegraded, status, reason, msg, updateCheck, affectedPods, memoryLimit)
5557
}
58+
59+
func updateImageScanningConfigErrorCondition(config *v1alpha2.MondooAuditConfig, err error) {
60+
reason := "KubernetesContainerImageScanConfigInvalid"
61+
var labelSelectorErr invalidLabelSelectorError
62+
if errors.As(err, &labelSelectorErr) {
63+
reason = "InvalidLabelSelector"
64+
}
65+
config.Status.Conditions = mondoo.SetMondooAuditCondition(
66+
config.Status.Conditions,
67+
v1alpha2.K8sContainerImageScanningDegraded,
68+
corev1.ConditionTrue,
69+
reason,
70+
err.Error(),
71+
mondoo.UpdateConditionIfReasonOrMessageChange,
72+
[]string{},
73+
"",
74+
)
75+
}

controllers/container_image/deployment_handler.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ func (n *DeploymentHandler) syncConfigMap(ctx context.Context, clusterUid string
152152
desired, err := ConfigMap(integrationMrn, clusterUid, *n.Mondoo, *n.MondooOperatorConfig)
153153
if err != nil {
154154
logger.Error(err, "failed to generate desired ConfigMap with inventory")
155+
updateImageScanningConfigErrorCondition(n.Mondoo, err)
155156
return err
156157
}
157158

controllers/container_image/deployment_handler_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,27 @@ func (s *DeploymentHandlerSuite) TestReconcile_K8sContainerImageScanningStatus()
380380
s.Equal(corev1.ConditionFalse, condition.Status)
381381
}
382382

383+
func (s *DeploymentHandlerSuite) TestReconcile_InvalidLabelSelectorCondition() {
384+
s.auditConfig.Spec.Filtering.ObjectLabelSelector = &metav1.LabelSelector{
385+
MatchExpressions: []metav1.LabelSelectorRequirement{
386+
{Key: "track", Operator: metav1.LabelSelectorOpIn},
387+
},
388+
}
389+
d := s.createDeploymentHandler()
390+
s.NoError(d.KubeClient.Create(s.ctx, &s.auditConfig))
391+
392+
result, err := d.Reconcile(s.ctx)
393+
s.Error(err)
394+
s.True(result.IsZero())
395+
396+
s.Require().Len(d.Mondoo.Status.Conditions, 1)
397+
condition := d.Mondoo.Status.Conditions[0]
398+
s.Equal("InvalidLabelSelector", condition.Reason)
399+
s.Contains(condition.Message, "filtering.objectLabelSelector")
400+
s.Equal(corev1.ConditionTrue, condition.Status)
401+
s.Equal(mondoov1alpha2.K8sContainerImageScanningDegraded, condition.Type)
402+
}
403+
383404
func (s *DeploymentHandlerSuite) TestReconcile_DisableContainerImageScanning() {
384405
d := s.createDeploymentHandler()
385406
mondooAuditConfig := &s.auditConfig

controllers/container_image/resources.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,19 @@ const (
3434
k8sOptionObjectLabelSelector = "object-label-selector"
3535
)
3636

37+
type invalidLabelSelectorError struct {
38+
field string
39+
err error
40+
}
41+
42+
func (e invalidLabelSelectorError) Error() string {
43+
return e.err.Error()
44+
}
45+
46+
func (e invalidLabelSelectorError) Unwrap() error {
47+
return e.err
48+
}
49+
3750
func CronJob(image, integrationMrn, clusterUid, privateRegistrySecretName string, m *v1alpha2.MondooAuditConfig, cfg v1alpha2.MondooOperatorConfig) *batchv1.CronJob {
3851
ls := CronJobLabels(*m)
3952

@@ -338,7 +351,10 @@ func addLabelSelectorOption(options map[string]string, optionName, fieldName str
338351
}
339352
parsed, err := metav1.LabelSelectorAsSelector(selector)
340353
if err != nil {
341-
return fmt.Errorf("invalid filtering.%s: %w", fieldName, err)
354+
return invalidLabelSelectorError{
355+
field: fieldName,
356+
err: fmt.Errorf("invalid filtering.%s: %w", fieldName, err),
357+
}
342358
}
343359
if parsed.Empty() {
344360
return nil

controllers/k8s_scan/conditions.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
package k8s_scan
55

66
import (
7+
"errors"
8+
79
"go.mondoo.com/mondoo-operator/api/v1alpha2"
810
"go.mondoo.com/mondoo-operator/pkg/utils/k8s"
911
"go.mondoo.com/mondoo-operator/pkg/utils/mondoo"
@@ -53,3 +55,21 @@ func updateWorkloadsConditions(config *v1alpha2.MondooAuditConfig, degradedStatu
5355
config.Status.Conditions = mondoo.SetMondooAuditCondition(
5456
config.Status.Conditions, v1alpha2.K8sResourcesScanningDegraded, status, reason, msg, updateCheck, affectedPods, memoryLimit)
5557
}
58+
59+
func updateWorkloadsConfigErrorCondition(config *v1alpha2.MondooAuditConfig, err error) {
60+
reason := "KubernetesResourcesScanConfigInvalid"
61+
var labelSelectorErr invalidLabelSelectorError
62+
if errors.As(err, &labelSelectorErr) {
63+
reason = "InvalidLabelSelector"
64+
}
65+
config.Status.Conditions = mondoo.SetMondooAuditCondition(
66+
config.Status.Conditions,
67+
v1alpha2.K8sResourcesScanningDegraded,
68+
corev1.ConditionTrue,
69+
reason,
70+
err.Error(),
71+
mondoo.UpdateConditionIfReasonOrMessageChange,
72+
[]string{},
73+
"",
74+
)
75+
}

controllers/k8s_scan/deployment_handler.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ func (n *DeploymentHandler) syncConfigMap(ctx context.Context, integrationMrn, c
269269
desired, err := ConfigMap(integrationMrn, clusterUid, *n.Mondoo, *n.MondooOperatorConfig)
270270
if err != nil {
271271
logger.Error(err, "failed to generate desired ConfigMap with inventory")
272+
updateWorkloadsConfigErrorCondition(n.Mondoo, err)
272273
return err
273274
}
274275

@@ -361,6 +362,7 @@ func (n *DeploymentHandler) syncExternalClusterConfigMap(ctx context.Context, in
361362
desired, err := ExternalClusterConfigMap(integrationMrn, clusterUid, cluster, *n.Mondoo, *n.MondooOperatorConfig)
362363
if err != nil {
363364
logger.Error(err, "failed to generate desired ConfigMap for external cluster", "cluster", cluster.Name)
365+
updateWorkloadsConfigErrorCondition(n.Mondoo, err)
364366
return err
365367
}
366368

controllers/k8s_scan/deployment_handler_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,59 @@ func (s *DeploymentHandlerSuite) TestReconcile_K8sResourceScanningStatus() {
210210
s.Equal(corev1.ConditionFalse, condition.Status)
211211
}
212212

213+
func (s *DeploymentHandlerSuite) TestReconcile_InvalidLabelSelectorCondition() {
214+
s.auditConfig.Spec.Filtering.NamespaceLabelSelector = &metav1.LabelSelector{
215+
MatchExpressions: []metav1.LabelSelectorRequirement{
216+
{Key: "tenant", Operator: metav1.LabelSelectorOpIn},
217+
},
218+
}
219+
d := s.createDeploymentHandler()
220+
s.NoError(d.KubeClient.Create(s.ctx, &s.auditConfig))
221+
222+
result, err := d.Reconcile(s.ctx)
223+
s.Error(err)
224+
s.True(result.IsZero())
225+
226+
s.Require().Len(d.Mondoo.Status.Conditions, 1)
227+
condition := d.Mondoo.Status.Conditions[0]
228+
s.Equal("InvalidLabelSelector", condition.Reason)
229+
s.Contains(condition.Message, "filtering.namespaceLabelSelector")
230+
s.Equal(corev1.ConditionTrue, condition.Status)
231+
s.Equal(mondoov1alpha2.K8sResourcesScanningDegraded, condition.Type)
232+
}
233+
234+
func (s *DeploymentHandlerSuite) TestReconcile_ExternalClusterInvalidLabelSelectorCondition() {
235+
s.auditConfig.Spec.KubernetesResources.Enable = false
236+
s.auditConfig.Spec.KubernetesResources.ExternalClusters = []mondoov1alpha2.ExternalCluster{
237+
{
238+
Name: "external",
239+
KubeconfigSecretRef: &corev1.LocalObjectReference{
240+
Name: "external-kubeconfig",
241+
},
242+
Filtering: &mondoov1alpha2.Filtering{
243+
ObjectLabelSelector: &metav1.LabelSelector{
244+
MatchExpressions: []metav1.LabelSelectorRequirement{
245+
{Key: "app", Operator: metav1.LabelSelectorOpIn},
246+
},
247+
},
248+
},
249+
},
250+
}
251+
d := s.createDeploymentHandler()
252+
s.NoError(d.KubeClient.Create(s.ctx, &s.auditConfig))
253+
254+
result, err := d.Reconcile(s.ctx)
255+
s.Error(err)
256+
s.True(result.IsZero())
257+
258+
s.Require().Len(d.Mondoo.Status.Conditions, 1)
259+
condition := d.Mondoo.Status.Conditions[0]
260+
s.Equal("InvalidLabelSelector", condition.Reason)
261+
s.Contains(condition.Message, "filtering.objectLabelSelector")
262+
s.Equal(corev1.ConditionTrue, condition.Status)
263+
s.Equal(mondoov1alpha2.K8sResourcesScanningDegraded, condition.Type)
264+
}
265+
213266
func (s *DeploymentHandlerSuite) TestReconcile_Disable() {
214267
d := s.createDeploymentHandler()
215268
mondooAuditConfig := &s.auditConfig

controllers/k8s_scan/resources.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,19 @@ const (
3232
k8sOptionObjectLabelSelector = "object-label-selector"
3333
)
3434

35+
type invalidLabelSelectorError struct {
36+
field string
37+
err error
38+
}
39+
40+
func (e invalidLabelSelectorError) Error() string {
41+
return e.err.Error()
42+
}
43+
44+
func (e invalidLabelSelectorError) Unwrap() error {
45+
return e.err
46+
}
47+
3548
// K8sDiscoveryTargets defines explicit targets for K8s resource scanning
3649
// (excludes container-images which is handled by the separate containers controller)
3750
var K8sDiscoveryTargets = []string{
@@ -1183,7 +1196,10 @@ func addLabelSelectorOption(options map[string]string, optionName, fieldName str
11831196

11841197
parsedSelector, err := metav1.LabelSelectorAsSelector(selector)
11851198
if err != nil {
1186-
return fmt.Errorf("invalid filtering.%s: %w", fieldName, err)
1199+
return invalidLabelSelectorError{
1200+
field: fieldName,
1201+
err: fmt.Errorf("invalid filtering.%s: %w", fieldName, err),
1202+
}
11871203
}
11881204
if !parsedSelector.Empty() {
11891205
options[optionName] = parsedSelector.String()

0 commit comments

Comments
 (0)