diff --git a/internal/api/annotations/annotations.go b/internal/api/annotations/annotations.go index a6bd6f6dd9..db59c3e013 100644 --- a/internal/api/annotations/annotations.go +++ b/internal/api/annotations/annotations.go @@ -21,6 +21,7 @@ const ( // remove in: 4.24 (tentative) or when 4.18 becomes the last supported version SELinuxPolicyConfigAnnotation = "config.node.openshift-kni.io/selinux-policy" SELinuxPolicyCustom = "custom" + SELinuxPolicyIgnore = "ignore" // introduced in: 4.18 // remove in: 5.2 (when branching 5.1 plan to address this https://redhat.atlassian.net/browse/CNF-23341 in main) @@ -53,6 +54,13 @@ func IsCustomPolicyEnabled(annot map[string]string) bool { return false } +func MustIgnoreCustomPolicy(annot map[string]string) bool { + if v, ok := annot[SELinuxPolicyConfigAnnotation]; ok && v == SELinuxPolicyIgnore { + return true + } + return false +} + func IsMultiplePoolsPerTreeEnabled(annot map[string]string) bool { if v, ok := annot[MultiplePoolsPerTreeAnnotation]; ok && v == MultiplePoolsPerTreeEnabled { return true diff --git a/internal/api/annotations/annotations_test.go b/internal/api/annotations/annotations_test.go index 37135df337..a7305b0ae8 100644 --- a/internal/api/annotations/annotations_test.go +++ b/internal/api/annotations/annotations_test.go @@ -36,6 +36,13 @@ func TestIsCustomPolicyEnabled(t *testing.T) { }, expected: false, }, + { + description: "annotation set to ignore does not enable custom policy", + annotations: map[string]string{ + SELinuxPolicyConfigAnnotation: "ignore", + }, + expected: false, + }, { description: "enabled custom policy", annotations: map[string]string{ @@ -53,6 +60,48 @@ func TestIsCustomPolicyEnabled(t *testing.T) { } } +func TestMustIgnoreCustomPolicy(t *testing.T) { + testcases := []struct { + description string + annotations map[string]string + expected bool + }{ + { + description: "empty map", + annotations: map[string]string{}, + expected: false, + }, + { + description: "annotation set to custom does not trigger ignore", + annotations: map[string]string{ + SELinuxPolicyConfigAnnotation: "custom", + }, + expected: false, + }, + { + description: "annotation set to arbitrary value does not trigger ignore", + annotations: map[string]string{ + SELinuxPolicyConfigAnnotation: "true", + }, + expected: false, + }, + { + description: "annotation set to ignore", + annotations: map[string]string{ + SELinuxPolicyConfigAnnotation: "ignore", + }, + expected: true, + }, + } + for _, tc := range testcases { + t.Run(tc.description, func(t *testing.T) { + if got := MustIgnoreCustomPolicy(tc.annotations); got != tc.expected { + t.Errorf("expected %v got %v", tc.expected, got) + } + }) + } +} + func TestIsMultiplePoolsPerTreeEnabled(t *testing.T) { testcases := []struct { description string diff --git a/internal/api/annotations/helper/helper.go b/internal/api/annotations/helper/helper.go index e4339e3893..fa6cd4171f 100644 --- a/internal/api/annotations/helper/helper.go +++ b/internal/api/annotations/helper/helper.go @@ -29,3 +29,12 @@ func IsCustomPolicyEnabled(instance *nropv1.NUMAResourcesOperator) bool { } return false } + +func MustIgnoreCustomPolicy(instance *nropv1.NUMAResourcesOperator) bool { + for _, ng := range instance.Spec.NodeGroups { + if anns.MustIgnoreCustomPolicy(ng.Annotations) { + return true + } + } + return false +} diff --git a/internal/api/annotations/helper/helper_test.go b/internal/api/annotations/helper/helper_test.go index 22adbdfc0e..f2a8f7d80c 100644 --- a/internal/api/annotations/helper/helper_test.go +++ b/internal/api/annotations/helper/helper_test.go @@ -139,3 +139,103 @@ func TestIsCustomPolicyEnabled(t *testing.T) { }) } } + +func TestMustIgnoreCustomPolicy(t *testing.T) { + testcases := []struct { + description string + nodeGroups []nropv1.NodeGroup + expected bool + }{ + { + description: "empty maps - single", + nodeGroups: []nropv1.NodeGroup{ + { + Annotations: make(map[string]string), + }, + }, + expected: false, + }, + { + description: "empty maps - multi", + nodeGroups: []nropv1.NodeGroup{ + { + Annotations: make(map[string]string), + }, + { + Annotations: make(map[string]string), + }, + { + Annotations: make(map[string]string), + }, + }, + expected: false, + }, + { + description: "annotation set to custom does not trigger ignore - single", + nodeGroups: []nropv1.NodeGroup{ + { + Annotations: map[string]string{ + anns.SELinuxPolicyConfigAnnotation: "custom", + }, + }, + }, + expected: false, + }, + { + description: "annotation set to ignore - single", + nodeGroups: []nropv1.NodeGroup{ + { + Annotations: map[string]string{ + anns.SELinuxPolicyConfigAnnotation: "ignore", + }, + }, + }, + expected: true, + }, + { + description: "annotation set to ignore - multi", + nodeGroups: []nropv1.NodeGroup{ + { + Annotations: make(map[string]string), + }, + { + Annotations: map[string]string{ + anns.SELinuxPolicyConfigAnnotation: "ignore", + }, + }, + { + Annotations: make(map[string]string), + }, + }, + expected: true, + }, + { + description: "annotation set to ignore - multi + mixed", + nodeGroups: []nropv1.NodeGroup{ + { + Annotations: map[string]string{ + anns.SELinuxPolicyConfigAnnotation: "custom", + }, + }, + { + Annotations: map[string]string{ + anns.SELinuxPolicyConfigAnnotation: "ignore", + }, + }, + { + Annotations: make(map[string]string), + }, + }, + expected: true, + }, + } + for _, tc := range testcases { + t.Run(tc.description, func(t *testing.T) { + nropObj := nropv1.NUMAResourcesOperator{} + nropObj.Spec.NodeGroups = tc.nodeGroups + if got := MustIgnoreCustomPolicy(&nropObj); got != tc.expected { + t.Errorf("expected %v got %v", tc.expected, got) + } + }) + } +} diff --git a/pkg/objectstate/rte/machineconfigpool.go b/pkg/objectstate/rte/machineconfigpool.go index c5ef3a6969..1566753b9d 100644 --- a/pkg/objectstate/rte/machineconfigpool.go +++ b/pkg/objectstate/rte/machineconfigpool.go @@ -145,6 +145,7 @@ func (em *ExistingManifests) MachineConfigsState(mf Manifests) ([]MachineConfigO } for _, tree := range em.trees { isCustomPolicy := annotations.IsCustomPolicyEnabled(tree.NodeGroup.Annotations) + mustIgnore := annotations.MustIgnoreCustomPolicy(tree.NodeGroup.Annotations) for _, mcp := range tree.MachineConfigPools { // do not update state when MachineConfigPool is paused if mcp.Spec.Paused { @@ -164,6 +165,11 @@ func (em *ExistingManifests) MachineConfigsState(mf Manifests) ([]MachineConfigO continue } + if mustIgnore { + klog.V(4).Infof("ignoring MachineConfig for pool %q", mcp.Name) + continue + } + if !isCustomPolicy { // caution here: we want a *nil interface value*, not an *interface which points to nil*. // the latter would lead to apparently correct code leading to runtime panics. See: