Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to create partial Constraint resources for policies with parameters #225

Merged
merged 1 commit into from Jan 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 5 additions & 4 deletions docs/cli/konstraint_create.md
Expand Up @@ -22,10 +22,11 @@ Create constraints with the Gatekeeper enforcement action set to dryrun
### Options

```
-d, --dryrun Sets the enforcement action of the constraints to dryrun, overriding the @enforcement tag
-h, --help help for create
-o, --output string Specify an output directory for the Gatekeeper resources
--skip-constraints Skip generation of constraints
-d, --dryrun Sets the enforcement action of the constraints to dryrun, overriding the @enforcement tag
-h, --help help for create
-o, --output string Specify an output directory for the Gatekeeper resources
--partial-constriants Generate partial Constraints for policies with parameters
--skip-constraints Skip generation of constraints
```

### SEE ALSO
Expand Down
27 changes: 23 additions & 4 deletions internal/commands/create.go
Expand Up @@ -38,18 +38,18 @@ Create constraints with the Gatekeeper enforcement action set to dryrun
if err := viper.BindPFlag("dryrun", cmd.PersistentFlags().Lookup("dryrun")); err != nil {
return fmt.Errorf("bind dryrun flag: %w", err)
}

if err := viper.BindPFlag("output", cmd.PersistentFlags().Lookup("output")); err != nil {
return fmt.Errorf("bind output flag: %w", err)
}

if err := viper.BindPFlag("skip-constraints", cmd.PersistentFlags().Lookup("skip-constraints")); err != nil {
return fmt.Errorf("bind skip-constraints flag: %w", err)
}

if err := viper.BindPFlag("constraint-template-version", cmd.PersistentFlags().Lookup("constraint-template-version")); err != nil {
return fmt.Errorf("bind constraint-template-version flag: %w", err)
}
if err := viper.BindPFlag("partial-constraints", cmd.PersistentFlags().Lookup("partial-constraints")); err != nil {
return fmt.Errorf("bind partial-constraints flag: %w", err)
}

path := "."
if len(args) > 0 {
Expand All @@ -64,6 +64,7 @@ Create constraints with the Gatekeeper enforcement action set to dryrun
cmd.PersistentFlags().BoolP("dryrun", "d", false, "Sets the enforcement action of the constraints to dryrun, overriding the @enforcement tag")
cmd.PersistentFlags().Bool("skip-constraints", false, "Skip generation of constraints")
cmd.PersistentFlags().String("constraint-template-version", "v1beta1", "Set the version of ConstraintTemplates")
cmd.PersistentFlags().Bool("partial-constraints", false, "Generate partial Constraints for policies with parameters")

return &cmd
}
Expand Down Expand Up @@ -124,7 +125,7 @@ func runCreateCommand(path string) error {
}

// Skip Constraint generation if there are parameters on the template.
if len(violation.Parameters()) > 0 {
if len(violation.Parameters()) > 0 && !viper.GetBool("partial-constraints") {
logger.Warn("skipping constraint generation due to use of parameters")
continue
}
Expand Down Expand Up @@ -286,9 +287,27 @@ func getConstraint(violation rego.Rego) (unstructured.Unstructured, error) {
}
}

if len(violation.Parameters()) > 0 && viper.GetBool("partial-constraints") {
if err := addParametersToConstraint(&constraint, violation.Parameters()); err != nil {
return unstructured.Unstructured{}, fmt.Errorf("add parameters %v to constraint: %w", violation.Parameters(), err)
}
}

return constraint, nil
}

func addParametersToConstraint(constraint *unstructured.Unstructured, parameters []rego.Parameter) error {
params := make(map[string]interface{}, len(parameters))
for _, p := range parameters {
params[p.Name] = nil
}
if err := unstructured.SetNestedField(constraint.Object, params, "spec", "parameters"); err != nil {
return fmt.Errorf("set parameters map: %w", err)
}

return nil
}

func setKindMatcher(constraint *unstructured.Unstructured, kindMatchers []rego.KindMatcher) error {
var kinds []string
var apiGroups []string
Expand Down