@@ -30,8 +30,10 @@ import (
3030 "k8s.io/apimachinery/pkg/types"
3131 "k8s.io/client-go/dynamic"
3232 dynfake "k8s.io/client-go/dynamic/fake"
33+ "k8s.io/client-go/kubernetes"
3334 clientsetfake "k8s.io/client-go/kubernetes/fake"
3435 "k8s.io/client-go/kubernetes/scheme"
36+ "k8s.io/client-go/tools/clientcmd"
3537 "k8s.io/client-go/tools/record"
3638 klog "k8s.io/klog/v2"
3739 parentpolicyv1 "open-cluster-management.io/governance-policy-propagator/api/v1"
@@ -57,11 +59,6 @@ func (d *DryRunner) dryRun(cmd *cobra.Command, args []string) error {
5759 return fmt .Errorf ("unable to read input policy: %w" , err )
5860 }
5961
60- inputObjects , err := d .readInputResources (cmd , args )
61- if err != nil {
62- return fmt .Errorf ("unable to read input resources: %w" , err )
63- }
64-
6562 if err := d .setupLogs (); err != nil {
6663 return fmt .Errorf ("unable to setup the logging configuration: %w" , err )
6764 }
@@ -74,9 +71,16 @@ func (d *DryRunner) dryRun(cmd *cobra.Command, args []string) error {
7471 return fmt .Errorf ("unable to setup the dryrun reconciler: %w" , err )
7572 }
7673
77- err = d .applyInputResources (ctx , rec , inputObjects )
78- if err != nil {
79- return fmt .Errorf ("unable to apply input resources: %w" , err )
74+ if ! d .fromCluster {
75+ inputObjects , err := d .readInputResources (cmd , args )
76+ if err != nil {
77+ return fmt .Errorf ("unable to read input resources: %w" , err )
78+ }
79+
80+ err = d .applyInputResources (ctx , rec , inputObjects )
81+ if err != nil {
82+ return fmt .Errorf ("unable to apply input resources: %w" , err )
83+ }
8084 }
8185
8286 cfgPolicyNN := types.NamespacedName {
@@ -332,10 +336,12 @@ func (d *DryRunner) readInputResources(cmd *cobra.Command, args []string) (
332336 return rawInputs , nil
333337}
334338
339+ // applyInputResources applies the user's resources to the fake cluster
335340func (d * DryRunner ) applyInputResources (
336- ctx context.Context , rec * ctrl.ConfigurationPolicyReconciler , inputObjects []* unstructured.Unstructured ,
341+ ctx context.Context ,
342+ rec * ctrl.ConfigurationPolicyReconciler ,
343+ inputObjects []* unstructured.Unstructured ,
337344) error {
338- // Apply the user's resources to the fake cluster
339345 for _ , obj := range inputObjects {
340346 gvk := obj .GroupVersionKind ()
341347
@@ -346,7 +352,7 @@ func (d *DryRunner) applyInputResources(
346352 "entry in the mappings file" , err , gvk .Kind )
347353 }
348354
349- return fmt . Errorf ( "unable to apply an input resource: %w" , err )
355+ return err
350356 }
351357
352358 var resInt dynamic.ResourceInterface
@@ -365,7 +371,7 @@ func (d *DryRunner) applyInputResources(
365371
366372 if _ , err := resInt .Create (ctx , obj , metav1.CreateOptions {}); err != nil &&
367373 ! k8serrors .IsAlreadyExists (err ) {
368- return fmt . Errorf ( "unable to apply an input resource: %w" , err )
374+ return err
369375 }
370376
371377 // Manually convert resources from the dynamic client to the runtime client
@@ -428,11 +434,60 @@ func (d *DryRunner) setupReconciler(
428434 return nil , err
429435 }
430436
431- dynamicClient := dynfake .NewSimpleDynamicClient (scheme .Scheme )
432- clientset := clientsetfake .NewSimpleClientset ()
437+ runtimeClient := clientfake .NewClientBuilder ().
438+ WithScheme (scheme .Scheme ).
439+ WithObjects (configPolCRD , cfgPolicy ).
440+ WithStatusSubresource (cfgPolicy ).
441+ Build ()
442+
443+ nsSelUpdatesChan := make (chan event.GenericEvent , 20 )
444+
433445 watcherReconciler , _ := depclient .NewControllerRuntimeSource ()
434446
435- dynamicWatcher := depclient .NewWithClients (
447+ var dynamicWatcher depclient.DynamicWatcher
448+ var clientset kubernetes.Interface
449+ var dynamicClient dynamic.Interface
450+ var nsSelReconciler common.NamespaceSelectorReconciler
451+
452+ if d .fromCluster {
453+ loadingRules := clientcmd .NewDefaultClientConfigLoadingRules ()
454+ clientConfig := clientcmd .NewNonInteractiveDeferredLoadingClientConfig (
455+ loadingRules , & clientcmd.ConfigOverrides {},
456+ )
457+
458+ kubeConfig , err := clientConfig .ClientConfig ()
459+ if err != nil {
460+ return nil , fmt .Errorf ("unable to locate the default kubeconfig: %w" , err )
461+ }
462+
463+ clientset , err = kubernetes .NewForConfig (kubeConfig )
464+ if err != nil {
465+ return nil , fmt .Errorf ("failed to create kubernetes clientset for cluster: %w" , err )
466+ }
467+
468+ dynamicClient , err = dynamic .NewForConfig (kubeConfig )
469+ if err != nil {
470+ return nil , fmt .Errorf ("failed to create dynamic client for cluster: %w" , err )
471+ }
472+
473+ readOnlyMode := true // Prevent modifications to the cluster
474+
475+ realRuntimeClient , err := client .New (kubeConfig , client.Options {
476+ Scheme : scheme .Scheme ,
477+ DryRun : & readOnlyMode ,
478+ })
479+ if err != nil {
480+ return nil , fmt .Errorf ("failed to create runtime client for ns selector reconciler: %w" , err )
481+ }
482+
483+ nsSelReconciler = common .NewNamespaceSelectorReconciler (realRuntimeClient , nsSelUpdatesChan )
484+ } else {
485+ dynamicClient = dynfake .NewSimpleDynamicClient (scheme .Scheme )
486+ clientset = clientsetfake .NewSimpleClientset ()
487+ nsSelReconciler = common .NewNamespaceSelectorReconciler (runtimeClient , nsSelUpdatesChan )
488+ }
489+
490+ dynamicWatcher = depclient .NewWithClients (
436491 dynamicClient ,
437492 clientset .Discovery (),
438493 watcherReconciler ,
@@ -446,14 +501,28 @@ func (d *DryRunner) setupReconciler(
446501 }
447502 }()
448503
449- runtimeClient := clientfake .NewClientBuilder ().
450- WithScheme (scheme .Scheme ).
451- WithObjects (configPolCRD , cfgPolicy ).
452- WithStatusSubresource (cfgPolicy ).
453- Build ()
504+ rec := ctrl.ConfigurationPolicyReconciler {
505+ Client : runtimeClient ,
506+ DecryptionConcurrency : 1 ,
507+ DynamicWatcher : dynamicWatcher ,
508+ Scheme : scheme .Scheme ,
509+ Recorder : record .NewFakeRecorder (8 ),
510+ InstanceName : "policy-cli" ,
511+ TargetK8sClient : clientset ,
512+ TargetK8sDynamicClient : dynamicClient ,
513+ SelectorReconciler : & nsSelReconciler ,
514+ EnableMetrics : false ,
515+ UninstallMode : false ,
516+ EvalBackoffSeconds : 5 ,
517+ FullDiffs : d .fullDiffs ,
518+ }
454519
455- nsSelUpdatesChan := make (chan event.GenericEvent , 20 )
456- nsSelReconciler := common .NewNamespaceSelectorReconciler (runtimeClient , nsSelUpdatesChan )
520+ // wait for dynamic watcher to have started
521+ <- rec .DynamicWatcher .Started ()
522+
523+ if d .fromCluster {
524+ return & rec , nil
525+ }
457526
458527 defaultNs := & unstructured.Unstructured {
459528 Object : map [string ]interface {}{
@@ -478,21 +547,7 @@ func (d *DryRunner) setupReconciler(
478547 return nil , err
479548 }
480549
481- rec := ctrl.ConfigurationPolicyReconciler {
482- Client : runtimeClient ,
483- DecryptionConcurrency : 1 ,
484- DynamicWatcher : dynamicWatcher ,
485- Scheme : scheme .Scheme ,
486- Recorder : record .NewFakeRecorder (8 ),
487- InstanceName : "policy-cli" ,
488- TargetK8sClient : clientset ,
489- TargetK8sDynamicClient : dynamicClient ,
490- SelectorReconciler : & nsSelReconciler ,
491- EnableMetrics : false ,
492- UninstallMode : false ,
493- EvalBackoffSeconds : 5 ,
494- FullDiffs : d .fullDiffs ,
495- }
550+ fakeClientset := clientset .(* clientsetfake.Clientset )
496551
497552 if d .mappingsPath != "" {
498553 mFile , err := os .ReadFile (d .mappingsPath )
@@ -505,19 +560,16 @@ func (d *DryRunner) setupReconciler(
505560 return nil , err
506561 }
507562
508- clientset .Resources = mappings .ResourceLists (apiMappings )
563+ fakeClientset .Resources = mappings .ResourceLists (apiMappings )
509564 } else {
510- clientset .Resources , err = mappings .DefaultResourceLists ()
565+ fakeClientset .Resources , err = mappings .DefaultResourceLists ()
511566 if err != nil {
512567 return nil , err
513568 }
514569 }
515570
516571 // Add open-cluster-management policy CRD
517- addSupportedResources (clientset )
518-
519- // wait for dynamic watcher to have started
520- <- rec .DynamicWatcher .Started ()
572+ addSupportedResources (fakeClientset )
521573
522574 return & rec , nil
523575}
0 commit comments