Skip to content

Commit

Permalink
Improve dryrun docs and errors
Browse files Browse the repository at this point in the history
The command is now correctly marked as a dev preview feature. Errors
are now generally wrapped to give some indication of where they came
from, and if a resource failed to be applied because of a (likely)
missing mapping, the error message now suggests how to fix it.

Signed-off-by: Justin Kulikauskas <[email protected]>
  • Loading branch information
JustinKuli authored and openshift-merge-bot[bot] committed Sep 27, 2024
1 parent 14b1eff commit 9172504
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 17 deletions.
13 changes: 8 additions & 5 deletions cmd/dryrun/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ var ErrNonCompliant = errors.New("policy is NonCompliant")
func (d *DryRunner) GetCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "dryrun",
Short: "Locally execute a ConfigurationPolicy",
Long: "Locally execute a ConfigurationPolicy",
RunE: d.dryRun,
Args: cobra.ArbitraryArgs,
Short: "(Dev Preview feature) Locally execute a ConfigurationPolicy",
Long: "(Dev Preview feature) Locally execute a ConfigurationPolicy against input files " +
"representing the cluster state, and view the diffs and any compliance events that " +
"would be generated.",
RunE: d.dryRun,
Args: cobra.ArbitraryArgs,
}

cmd.Flags().StringVarP(
Expand Down Expand Up @@ -87,7 +89,8 @@ func (d *DryRunner) GetCmd() *cobra.Command {
RunE: mappings.GenerateMappings,
})

cmd.SetOut(os.Stdout) // sets default output to stdout, otherwise it is stderr
cmd.SetOut(os.Stdout) // sets default output to stdout, otherwise it is stderr
cmd.SilenceUsage = true // otherwise all errors will be followed by the usage doc

return cmd
}
Expand Down
27 changes: 15 additions & 12 deletions cmd/dryrun/dryrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,24 @@ import (
func (d *DryRunner) dryRun(cmd *cobra.Command, args []string) error {
cfgPolicy, err := d.readPolicy(cmd)
if err != nil {
return err
return fmt.Errorf("unable to read input policy: %w", err)
}

inputObjects, err := d.readInputResources(cmd, args)
if err != nil {
return err
return fmt.Errorf("unable to read input resources: %w", err)
}

if err := d.setupLogs(); err != nil {
return err
return fmt.Errorf("unable to setup the logging configuration: %w", err)
}

ctx, cancel := context.WithCancel(cmd.Context())
defer cancel()

rec, err := d.setupReconciler(ctx, cfgPolicy)
if err != nil {
return err
return fmt.Errorf("unable to setup the dryrun reconciler: %w", err)
}

// Apply the user's resources to the fake cluster
Expand All @@ -72,7 +72,12 @@ func (d *DryRunner) dryRun(cmd *cobra.Command, args []string) error {

scopedGVR, err := rec.DynamicWatcher.GVKToGVR(gvk)
if err != nil {
return err
if errors.Is(depclient.ErrNoVersionedResource, err) {
return fmt.Errorf("%w for kind %v: if this is a custom resource, it may need an "+
"entry in the mappings file", err, gvk.Kind)
}

return fmt.Errorf("unable to apply an input resource: %w", err)
}

var resInt dynamic.ResourceInterface
Expand All @@ -84,7 +89,7 @@ func (d *DryRunner) dryRun(cmd *cobra.Command, args []string) error {
}

if _, err := resInt.Create(ctx, obj, metav1.CreateOptions{}); err != nil {
return err
return fmt.Errorf("unable to apply an input resource: %w", err)
}
}

Expand All @@ -94,16 +99,16 @@ func (d *DryRunner) dryRun(cmd *cobra.Command, args []string) error {
}

if _, err := rec.Reconcile(ctx, runtime.Request{NamespacedName: cfgPolicyNN}); err != nil {
return err
return fmt.Errorf("unable to complete the dryrun reconcile: %w", err)
}

if err := rec.Get(ctx, cfgPolicyNN, cfgPolicy); err != nil {
return err
return fmt.Errorf("unable to get the resulting policy state: %w", err)
}

if d.statusPath != "" {
if err := d.saveStatus(cfgPolicy.Status); err != nil {
return err
return fmt.Errorf("unable to save the resulting policy state: %w", err)
}
}

Expand All @@ -112,12 +117,10 @@ func (d *DryRunner) dryRun(cmd *cobra.Command, args []string) error {
}

if err := d.saveOrPrintComplianceMessages(ctx, cmd, rec.Client, cfgPolicy.Namespace); err != nil {
return err
return fmt.Errorf("unable to save or print the compliance messages: %w", err)
}

if cfgPolicy.Status.ComplianceState != policyv1.Compliant {
cmd.SilenceUsage = true

return ErrNonCompliant
}

Expand Down

0 comments on commit 9172504

Please sign in to comment.