From 8a46dc4f29aead1a2514a0cbaeb7bc0deb4beab7 Mon Sep 17 00:00:00 2001 From: Brandon Palm Date: Thu, 23 Apr 2026 11:44:41 -0500 Subject: [PATCH] CNF-23094: Propagate context through pkg/utils public API Replace context.TODO() with a ctx parameter in all pkg/utils functions that make Kubernetes API calls. Callers that already have context available now pass it through; remaining callers use context.TODO() temporarily until their packages are updated. Additionally: - Wire backoff.WithContext so retries in GetObjectIfFound respect context cancellation - Hoist ValidatePriorityClassExist out of the per-node loop in nodeScanTypeHandler.createScanWorkload to avoid redundant API calls --- cmd/manager/aggregator.go | 2 +- cmd/manager/cel-scanner.go | 2 +- .../complianceremediation_controller.go | 2 +- .../compliancescan/compliancescan_controller.go | 4 ++-- pkg/controller/compliancescan/resultserver.go | 2 +- pkg/controller/compliancescan/scantype.go | 12 ++++++++---- .../compliancesuite/compliancesuite_controller.go | 2 +- pkg/controller/compliancesuite/suitererunner.go | 2 +- pkg/utils/clientutils.go | 6 +++--- pkg/utils/nodeutils.go | 4 ++-- pkg/utils/podutils.go | 4 ++-- pkg/utils/remediationutils.go | 4 ++-- pkg/utils/rule_metadata.go | 4 ++-- pkg/utils/rule_metadata_test.go | 7 ++++--- 14 files changed, 31 insertions(+), 26 deletions(-) diff --git a/cmd/manager/aggregator.go b/cmd/manager/aggregator.go index e361407abc..66a02e5d5a 100644 --- a/cmd/manager/aggregator.go +++ b/cmd/manager/aggregator.go @@ -577,7 +577,7 @@ func createResults(crClient aggregatorCrClient, scan *compv1alpha1.ComplianceSca // Build a cache of custom labels/annotations from Rule objects so that // we can propagate user-defined metadata to ComplianceCheckResults. - ruleMetadataCache, err := utils.NewRuleMetadataCache(crClient.getClient(), scan.Namespace) + ruleMetadataCache, err := utils.NewRuleMetadataCache(context.TODO(), crClient.getClient(), scan.Namespace) if err != nil { // Non-fatal: if we can't build the cache, we just won't propagate custom metadata. cmdLog.Info("Warning: could not build rule metadata cache, custom labels/annotations will not be propagated", "error", err) diff --git a/cmd/manager/cel-scanner.go b/cmd/manager/cel-scanner.go index bc7a856f73..847d6299f2 100644 --- a/cmd/manager/cel-scanner.go +++ b/cmd/manager/cel-scanner.go @@ -509,7 +509,7 @@ func (c *CelScanner) runPlatformScan() { foundCheckResult.TypeMeta = pr.TypeMeta cmdLog.Info("Getting ComplianceCheckResult", "ComplianceCheckResult.Name", crkey.Name, "ComplianceCheckResult.Namespace", crkey.Namespace) - checkResultExists := utils.GetObjectIfFound(c.client, crkey, foundCheckResult) + checkResultExists := utils.GetObjectIfFound(context.TODO(), c.client, crkey, foundCheckResult) if checkResultExists { foundCheckResult.ObjectMeta.DeepCopyInto(&pr.ObjectMeta) } else if !scan.Spec.ShowNotApplicable && pr.Status == cmpv1alpha1.CheckResultNotApplicable { diff --git a/pkg/controller/complianceremediation/complianceremediation_controller.go b/pkg/controller/complianceremediation/complianceremediation_controller.go index 330a8549ba..a1813dbd66 100644 --- a/pkg/controller/complianceremediation/complianceremediation_controller.go +++ b/pkg/controller/complianceremediation/complianceremediation_controller.go @@ -709,7 +709,7 @@ func (r *ReconcileComplianceRemediation) verifyAndCompleteKC(obj *unstructured.U } // We need to get name of original kubelet config that used to generate this kubeletconfig machine config // if we can't find owner of generated mc, we will create custom kubeletconfig instead - kubeletConfig, err := utils.GetKCFromMC(kubeletMC, r.Client) + kubeletConfig, err := utils.GetKCFromMC(context.TODO(), kubeletMC, r.Client) if err != nil { return fmt.Errorf("couldn't get kubelet config from machine config: %w", err) } diff --git a/pkg/controller/compliancescan/compliancescan_controller.go b/pkg/controller/compliancescan/compliancescan_controller.go index de9fdde3f9..84b1352ada 100644 --- a/pkg/controller/compliancescan/compliancescan_controller.go +++ b/pkg/controller/compliancescan/compliancescan_controller.go @@ -756,7 +756,7 @@ func (r *ReconcileComplianceScan) phaseAggregatingHandler(h scanTypeHandler, log logger.Info("Creating an aggregator pod for scan") aggregator := r.newAggregatorPod(instance, logger) - if priorityClassExist, why := utils.ValidatePriorityClassExist(aggregator.Spec.PriorityClassName, r.Client); !priorityClassExist { + if priorityClassExist, why := utils.ValidatePriorityClassExist(context.TODO(), aggregator.Spec.PriorityClassName, r.Client); !priorityClassExist { logger.Info(why, "aggregator", aggregator.Name) r.Recorder.Eventf(aggregator, corev1.EventTypeWarning, "PriorityClass", why+" aggregator:"+aggregator.Name) aggregator.Spec.PriorityClassName = "" @@ -1025,7 +1025,7 @@ func (r *ReconcileComplianceScan) generateResultEventForScan(scan *compv1alpha1. compv1alpha1.ComplianceCheckInconsistentLabel) } - err, haveOutdatedRems := utils.HaveOutdatedRemediations(r.Client) + err, haveOutdatedRems := utils.HaveOutdatedRemediations(context.TODO(), r.Client) if err != nil { logger.Info("Could not check if there exist any obsolete remediations", "Scan.Name", scan.Name) } diff --git a/pkg/controller/compliancescan/resultserver.go b/pkg/controller/compliancescan/resultserver.go index 1fa5024729..347d9722b3 100644 --- a/pkg/controller/compliancescan/resultserver.go +++ b/pkg/controller/compliancescan/resultserver.go @@ -43,7 +43,7 @@ func (r *ReconcileComplianceScan) createResultServer(instance *compv1alpha1.Comp return podUidErr } deployment := resultServer(instance, resultServerLabels, podFSGroup, podUid, logger) - if priorityClassExist, why := utils.ValidatePriorityClassExist(deployment.Spec.Template.Spec.PriorityClassName, r.Client); !priorityClassExist { + if priorityClassExist, why := utils.ValidatePriorityClassExist(ctx, deployment.Spec.Template.Spec.PriorityClassName, r.Client); !priorityClassExist { log.Info(why, "resultServer", deployment.Name) r.Recorder.Eventf(deployment, corev1.EventTypeWarning, "PriorityClass", why+" resultServer:"+deployment.Name) deployment.Spec.Template.Spec.PriorityClassName = "" diff --git a/pkg/controller/compliancescan/scantype.go b/pkg/controller/compliancescan/scantype.go index f04fbb1603..b05814cd28 100644 --- a/pkg/controller/compliancescan/scantype.go +++ b/pkg/controller/compliancescan/scantype.go @@ -137,15 +137,19 @@ func (nh *nodeScanTypeHandler) validate() (bool, error) { } func (nh *nodeScanTypeHandler) createScanWorkload() error { + priorityClassExist, why := utils.ValidatePriorityClassExist(context.TODO(), nh.scan.Spec.PriorityClass, nh.r.Client) + if !priorityClassExist { + nh.l.Info(why, "Scan.Name", nh.scan.Name) + nh.r.Recorder.Eventf(nh.scan, corev1.EventTypeWarning, "PriorityClass", why+" Scan:"+nh.scan.Name) + } + // On each eligible node.. for idx := range nh.nodes { node := &nh.nodes[idx] // ..schedule a pod.. nh.l.Info("Creating a pod for node", "Pod.Name", node.Name) pod := newScanPodForNode(nh.scan, node, nh.l) - if priorityClassExist, why := utils.ValidatePriorityClassExist(nh.scan.Spec.PriorityClass, nh.r.Client); !priorityClassExist { - nh.l.Info(why, "Scan.Name", nh.scan.Name) - nh.r.Recorder.Eventf(nh.scan, corev1.EventTypeWarning, "PriorityClass", why+" Scan:"+nh.scan.Name) + if !priorityClassExist { pod.Spec.PriorityClassName = "" } if err := nh.r.launchScanPod(nh.scan, pod, nh.l); err != nil { @@ -350,7 +354,7 @@ func (ph *platformScanTypeHandler) validate() (bool, error) { func (ph *platformScanTypeHandler) createScanWorkload() error { ph.l.Info("Creating a Platform scan pod") pod := ph.r.newPlatformScanPod(ph.scan, ph.l) - if priorityClassExist, why := utils.ValidatePriorityClassExist(ph.scan.Spec.PriorityClass, ph.r.Client); !priorityClassExist { + if priorityClassExist, why := utils.ValidatePriorityClassExist(context.TODO(), ph.scan.Spec.PriorityClass, ph.r.Client); !priorityClassExist { ph.r.Recorder.Eventf(ph.scan, corev1.EventTypeWarning, "PriorityClass", why+" Scan:"+ph.scan.Name) pod.Spec.PriorityClassName = "" } diff --git a/pkg/controller/compliancesuite/compliancesuite_controller.go b/pkg/controller/compliancesuite/compliancesuite_controller.go index 90b26d40e1..7b3cba20d2 100644 --- a/pkg/controller/compliancesuite/compliancesuite_controller.go +++ b/pkg/controller/compliancesuite/compliancesuite_controller.go @@ -392,7 +392,7 @@ func (r *ReconcileComplianceSuite) generateEventsForSuite(suite *compv1alpha1.Co compv1alpha1.ComplianceCheckInconsistentLabel) } - err, haveOutdatedRems := utils.HaveOutdatedRemediations(r.Client) + err, haveOutdatedRems := utils.HaveOutdatedRemediations(context.TODO(), r.Client) if err != nil { logger.Info("Could not check if there exist any obsolete remediations", "Suite.Name", suite.Name) } diff --git a/pkg/controller/compliancesuite/suitererunner.go b/pkg/controller/compliancesuite/suitererunner.go index ab960e2006..7384722774 100644 --- a/pkg/controller/compliancesuite/suitererunner.go +++ b/pkg/controller/compliancesuite/suitererunner.go @@ -25,7 +25,7 @@ func (r *ReconcileComplianceSuite) reconcileScanRerunnerCronJob(suite *compv1alp logger.Error(err, "Cannot get priority class name, scan will not be run with set priority class") } // this is a validation and should warn the user - if priorityClassExist, why := utils.ValidatePriorityClassExist(priorityClassName, r.Client); !priorityClassExist { + if priorityClassExist, why := utils.ValidatePriorityClassExist(context.TODO(), priorityClassName, r.Client); !priorityClassExist { log.Info(why, "Suite", suite.Name) r.Recorder.Eventf(suite, corev1.EventTypeWarning, "PriorityClass", why+" Suite:"+suite.Name) } diff --git a/pkg/utils/clientutils.go b/pkg/utils/clientutils.go index 951bf74d6b..efd8372bfb 100644 --- a/pkg/utils/clientutils.go +++ b/pkg/utils/clientutils.go @@ -19,10 +19,10 @@ var ( // It uses exponential backoff to retry on transient errors. // Returns true if the object was found, false if it doesn't exist. // The obj parameter will be updated with the retrieved object data if found. -func GetObjectIfFound(client runtimeclient.Client, key types.NamespacedName, obj runtimeclient.Object) bool { +func GetObjectIfFound(ctx context.Context, client runtimeclient.Client, key types.NamespacedName, obj runtimeclient.Object) bool { var found bool err := backoff.Retry(func() error { - err := client.Get(context.TODO(), key, obj) + err := client.Get(ctx, key, obj) if errors.IsNotFound(err) { // Not found is not an error we want to retry return nil @@ -32,7 +32,7 @@ func GetObjectIfFound(client runtimeclient.Client, key types.NamespacedName, obj } found = true return nil - }, backoff.WithMaxRetries(backoff.NewExponentialBackOff(), maxRetries)) + }, backoff.WithContext(backoff.WithMaxRetries(backoff.NewExponentialBackOff(), maxRetries), ctx)) if err != nil { log.Error(err, "Couldn't get object", "Name", key.Name, "Namespace", key.Namespace) diff --git a/pkg/utils/nodeutils.go b/pkg/utils/nodeutils.go index 3d1f7b3838..e40da27269 100644 --- a/pkg/utils/nodeutils.go +++ b/pkg/utils/nodeutils.go @@ -167,7 +167,7 @@ func GetScanType(annotations map[string]string) compliancev1alpha1.ComplianceSca return compliancev1alpha1.ScanTypePlatform } -func GetKCFromMC(mc *mcfgv1.MachineConfig, client runtimeclient.Client) (*mcfgv1.KubeletConfig, error) { +func GetKCFromMC(ctx context.Context, mc *mcfgv1.MachineConfig, client runtimeclient.Client) (*mcfgv1.KubeletConfig, error) { if mc == nil { return nil, fmt.Errorf("machine config is nil") } @@ -176,7 +176,7 @@ func GetKCFromMC(mc *mcfgv1.MachineConfig, client runtimeclient.Client) (*mcfgv1 kubeletName := mc.GetOwnerReferences()[0].Name kubeletConfig := &mcfgv1.KubeletConfig{} kcKey := types.NamespacedName{Name: kubeletName} - if err := client.Get(context.TODO(), kcKey, kubeletConfig); err != nil { + if err := client.Get(ctx, kcKey, kubeletConfig); err != nil { return nil, fmt.Errorf("couldn't get current KubeletConfig: %w", err) } return kubeletConfig, nil diff --git a/pkg/utils/podutils.go b/pkg/utils/podutils.go index fd1cd71940..262f5421af 100644 --- a/pkg/utils/podutils.go +++ b/pkg/utils/podutils.go @@ -24,12 +24,12 @@ func FindNewestPod(pods []corev1.Pod) *corev1.Pod { } // validate priority class exists by name -func ValidatePriorityClassExist(name string, client client.Client) (bool, string) { +func ValidatePriorityClassExist(ctx context.Context, name string, client client.Client) (bool, string) { if name == "" { return true, "" } priorityClass := &schedulev1.PriorityClass{} - err := client.Get(context.TODO(), types.NamespacedName{Name: name}, priorityClass) + err := client.Get(ctx, types.NamespacedName{Name: name}, priorityClass) if err != nil { return false, fmt.Sprintf("Error while getting priority class '%s', err: %s\n", name, err) } diff --git a/pkg/utils/remediationutils.go b/pkg/utils/remediationutils.go index 25cf809636..15fb2db7f2 100644 --- a/pkg/utils/remediationutils.go +++ b/pkg/utils/remediationutils.go @@ -29,13 +29,13 @@ func IsKubeletConfig(obj *unstructured.Unstructured) bool { return IsKind(obj, "KubeletConfig") } -func HaveOutdatedRemediations(client runtimeclient.Client) (error, bool) { +func HaveOutdatedRemediations(ctx context.Context, client runtimeclient.Client) (error, bool) { remList := &compv1alpha1.ComplianceRemediationList{} listOpts := runtimeclient.ListOptions{ LabelSelector: labels.SelectorFromSet(labels.Set{compv1alpha1.OutdatedRemediationLabel: ""}), } - if err := client.List(context.TODO(), remList, &listOpts); err != nil { + if err := client.List(ctx, remList, &listOpts); err != nil { return err, false } diff --git a/pkg/utils/rule_metadata.go b/pkg/utils/rule_metadata.go index e8b660553c..df643c079b 100644 --- a/pkg/utils/rule_metadata.go +++ b/pkg/utils/rule_metadata.go @@ -80,14 +80,14 @@ type RuleMetadataCache struct { // NewRuleMetadataCache creates a RuleMetadataCache by listing all Rule // objects in the given namespace and indexing them by the // compliance.openshift.io/rule annotation. -func NewRuleMetadataCache(client runtimeclient.Client, namespace string) (*RuleMetadataCache, error) { +func NewRuleMetadataCache(ctx context.Context, client runtimeclient.Client, namespace string) (*RuleMetadataCache, error) { cache := &RuleMetadataCache{ customLabels: make(map[string]map[string]string), customAnnotations: make(map[string]map[string]string), } ruleList := &compv1alpha1.RuleList{} - err := client.List(context.TODO(), ruleList, runtimeclient.InNamespace(namespace)) + err := client.List(ctx, ruleList, runtimeclient.InNamespace(namespace)) if err != nil { return nil, err } diff --git a/pkg/utils/rule_metadata_test.go b/pkg/utils/rule_metadata_test.go index fd1ab57c86..27d33ab750 100644 --- a/pkg/utils/rule_metadata_test.go +++ b/pkg/utils/rule_metadata_test.go @@ -1,6 +1,7 @@ package utils import ( + "context" "testing" compv1alpha1 "github.com/ComplianceAsCode/compliance-operator/pkg/apis/compliance/v1alpha1" @@ -225,7 +226,7 @@ func TestNewRuleMetadataCache(t *testing.T) { WithRuntimeObjects(rule1, rule2). Build() - cache, err := NewRuleMetadataCache(client, "openshift-compliance") + cache, err := NewRuleMetadataCache(context.Background(), client, "openshift-compliance") if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -271,7 +272,7 @@ func TestNewRuleMetadataCache(t *testing.T) { WithScheme(scheme). Build() - cache, err := NewRuleMetadataCache(client, "openshift-compliance") + cache, err := NewRuleMetadataCache(context.Background(), client, "openshift-compliance") if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -319,7 +320,7 @@ func TestRuleMetadataCacheIntegration(t *testing.T) { WithRuntimeObjects(rule). Build() - cache, err := NewRuleMetadataCache(client, "openshift-compliance") + cache, err := NewRuleMetadataCache(context.Background(), client, "openshift-compliance") if err != nil { t.Fatalf("unexpected error building cache: %v", err) }