@@ -1037,9 +1037,15 @@ func (r *ConfigurationPolicyReconciler) handleObjectTemplates(plc *policyv1.Conf
10371037 resolverToUse = tmplResolver
10381038 }
10391039
1040- desiredObjects , scopedGVR , errEvent , err := r .determineDesiredObjects (
1040+ desiredObjects , scopedGVR , determinedRelatedObjects , errEvent , err := r .determineDesiredObjects (
10411041 plc , index , objectT , resolverToUse , resolveOptions ,
10421042 )
1043+
1044+ // Merge the related objects returned from determineDesiredObjects into the outer relatedObjects
1045+ for _ , object := range determinedRelatedObjects {
1046+ relatedObjects = addOrUpdateRelatedObject (relatedObjects , object )
1047+ }
1048+
10431049 if err != nil {
10441050 // Return all mapping and templating errors encountered and let the caller decide if the errors should be
10451051 // retried
@@ -1319,6 +1325,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
13191325) (
13201326 []* unstructured.Unstructured ,
13211327 * depclient.ScopedGVR ,
1328+ []policyv1.RelatedObject ,
13221329 * objectTmplEvalEvent ,
13231330 error ,
13241331) {
@@ -1339,7 +1346,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
13391346 message : "Error parsing the namespace from the object definition" ,
13401347 }
13411348
1342- return nil , nil , errEvent , err
1349+ return nil , nil , nil , errEvent , err
13431350 }
13441351
13451352 objGVK := parsedMinMetadata .GroupVersionKind ()
@@ -1354,7 +1361,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
13541361 ),
13551362 }
13561363
1357- return nil , nil , errEvent , nil
1364+ return nil , nil , nil , errEvent , nil
13581365 }
13591366
13601367 skippedObjMsg := "All objects of kind %s were skipped by the `skipObject` template function"
@@ -1384,7 +1391,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
13841391 message : fmt .Sprintf (skippedObjMsg , objGVK .Kind ),
13851392 }
13861393
1387- return []* unstructured.Unstructured {}, nil , event , nil
1394+ return []* unstructured.Unstructured {}, nil , nil , event , nil
13881395 }
13891396 }
13901397
@@ -1394,7 +1401,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
13941401 message : err .Error (),
13951402 }
13961403
1397- return nil , nil , errEvent , err
1404+ return nil , nil , nil , errEvent , err
13981405 }
13991406
14001407 // Set up relevant object namespace-name-objects map to populate with the
@@ -1451,7 +1458,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
14511458 message : msg ,
14521459 }
14531460
1454- return nil , & scopedGVR , errEvent , err
1461+ return nil , & scopedGVR , nil , errEvent , err
14551462 }
14561463
14571464 // Fetch object when:
@@ -1516,7 +1523,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
15161523
15171524 errEvent := & objectTmplEvalEvent {false , "K8s missing namespace" , msg }
15181525
1519- return nil , & scopedGVR , errEvent , nil
1526+ return nil , & scopedGVR , nil , errEvent , nil
15201527 }
15211528
15221529 // Fetch related objects from the cluster
@@ -1540,7 +1547,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
15401547 message : msg ,
15411548 }
15421549
1543- return nil , & scopedGVR , errEvent , err
1550+ return nil , & scopedGVR , nil , errEvent , err
15441551 }
15451552 } else {
15461553 existingObj , _ = getObject (desiredNs , desiredName , scopedGVR , r .TargetK8sDynamicClient )
@@ -1569,7 +1576,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
15691576 message : msg ,
15701577 }
15711578
1572- return nil , & scopedGVR , errEvent , err
1579+ return nil , & scopedGVR , nil , errEvent , err
15731580 }
15741581
15751582 listOpts := metav1.ListOptions {
@@ -1612,7 +1619,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
16121619 message : msg ,
16131620 }
16141621
1615- return nil , & scopedGVR , errEvent , err
1622+ return nil , & scopedGVR , nil , errEvent , err
16161623 }
16171624
16181625 // Populate objects from objectSelector results
@@ -1713,7 +1720,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
17131720 message : complianceMsg ,
17141721 }
17151722
1716- return nil , & scopedGVR , errEvent , err
1723+ return nil , & scopedGVR , nil , errEvent , err
17171724 }
17181725
17191726 if objectT .RecordDiff == "" && resolvedTemplate .HasSensitiveData {
@@ -1753,7 +1760,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
17531760 index , plc .Name , err ),
17541761 }
17551762
1756- return nil , & scopedGVR , errEvent , err
1763+ return nil , & scopedGVR , nil , errEvent , err
17571764 }
17581765
17591766 // Populate the namespace and name if applicable
@@ -1780,7 +1787,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
17801787 "from the namespace selector after template resolution" ,
17811788 }
17821789
1783- return nil , & scopedGVR , errEvent , nil
1790+ return nil , & scopedGVR , nil , errEvent , nil
17841791 }
17851792
17861793 // Error if the namespace is templated and returns empty.
@@ -1799,7 +1806,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
17991806 ),
18001807 }
18011808
1802- return nil , & scopedGVR , errEvent , nil
1809+ return nil , & scopedGVR , nil , errEvent , nil
18031810 }
18041811
18051812 // Error if the name doesn't match the parsed name from the objectSelector
@@ -1811,7 +1818,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
18111818 "from the object selector after template resolution" ,
18121819 }
18131820
1814- return nil , & scopedGVR , errEvent , nil
1821+ return nil , & scopedGVR , nil , errEvent , nil
18151822 }
18161823
18171824 desiredObjects = append (desiredObjects , desiredObj )
@@ -1839,7 +1846,7 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
18391846 message : fmt .Sprintf (msg , objGVK .Kind ),
18401847 }
18411848
1842- return nil , & scopedGVR , event , nil
1849+ return nil , & scopedGVR , nil , event , nil
18431850 }
18441851
18451852 // For mustnothave with no name and with an object selector, filter the "desired" objects
@@ -1862,10 +1869,55 @@ func (r *ConfigurationPolicyReconciler) determineDesiredObjects(
18621869 }
18631870 }
18641871
1865- return targetedObjects , & scopedGVR , nil , nil
1872+ // If no objects were matched, return a compliant event since this is
1873+ // mustnothave and no objects were found.
1874+ if len (targetedObjects ) == 0 {
1875+ var namespaces []string
1876+ var relatedObjects []policyv1.RelatedObject
1877+
1878+ // Populate the related objects list with the objects
1879+ // that were matched by the object selector.
1880+ for ns := range relevantNsNames {
1881+ namespaces = append (namespaces , ns )
1882+
1883+ for name := range relevantNsNames [ns ] {
1884+ relatedObjects = addRelatedObjects (
1885+ true ,
1886+ scopedGVR ,
1887+ objGVK .Kind ,
1888+ ns ,
1889+ []string {name },
1890+ "" ,
1891+ nil ,
1892+ )
1893+ }
1894+ }
1895+
1896+ sort .Strings (namespaces )
1897+
1898+ nsMsg := "namespace"
1899+ if len (namespaces ) > 1 {
1900+ nsMsg = "namespaces:"
1901+ }
1902+
1903+ event := & objectTmplEvalEvent {
1904+ compliant : true ,
1905+ reason : "" ,
1906+ message : fmt .Sprintf (
1907+ "%s missing as expected in %s %s" ,
1908+ scopedGVR .Resource ,
1909+ nsMsg ,
1910+ strings .Join (namespaces , ", " ),
1911+ ),
1912+ }
1913+
1914+ return nil , & scopedGVR , relatedObjects , event , nil
1915+ }
1916+
1917+ return targetedObjects , & scopedGVR , nil , nil , nil
18661918 }
18671919
1868- return desiredObjects , & scopedGVR , nil , nil
1920+ return desiredObjects , & scopedGVR , nil , nil , nil
18691921}
18701922
18711923// batchedEvents combines compliance events into batches that should be emitted in order. For example,
0 commit comments