diff --git a/documentation/kyverno-cli.md b/documentation/kyverno-cli.md index fbfeef9269..85ff9d3b7f 100644 --- a/documentation/kyverno-cli.md +++ b/documentation/kyverno-cli.md @@ -1,5 +1,4 @@ -<small>*[documentation](/README.md#documentation) / kyverno-cli*</small> - +<small>_[documentation](/README.md#documentation) / kyverno-cli_</small> # Kyverno CLI @@ -40,39 +39,55 @@ yay -S kyverno-git Prints the version of kyverno used by the CLI. -Example: +Example: + ``` kyverno version ``` #### Validate -Validates a policy, can validate multiple policy resource description files or even an entire folder containing policy resource description -files. Currently supports files with resource description in yaml. + +Validates a policy, can validate multiple policy resource description files or even an entire folder containing policy resource description +files. Currently supports files with resource description in YAML. Example: + ``` kyverno validate /path/to/policy1.yaml /path/to/policy2.yaml /path/to/folderFullOfPolicies ``` #### Apply + Applies policies on resources, and supports applying multiple policies on multiple resources in a single command. Also supports applying the given policies to an entire cluster. The current kubectl context will be used to access the cluster. - Will return results to stdout. +Will return results to stdout. Apply to a resource: -``` + +```bash kyverno apply /path/to/policy.yaml --resource /path/to/resource.yaml ``` Apply to all matching resources in a cluster: -``` + +```bash kyverno apply /path/to/policy.yaml --cluster > policy-results.txt ``` Apply multiple policies to multiple resources: -``` + +```bash kyverno apply /path/to/policy1.yaml /path/to/folderFullOfPolicies --resource /path/to/resource1.yaml --resource /path/to/resource2.yaml --cluster ``` +##### Exit Codes -<small>*Read Next >> [Sample Policies](/samples/README.md)*</small> +The CLI exits with diffenent exit codes: + +| Message | Exit Code | +| ------------------------------------- | --------- | +| executes successfully | 0 | +| one or more policy rules are violated | 1 | +| policy validation failed | 2 | + +<small>_Read Next >> [Sample Policies](/samples/README.md)_</small> diff --git a/pkg/kyverno/apply/command.go b/pkg/kyverno/apply/command.go index e9f0b71bb3..5aa92e33f2 100644 --- a/pkg/kyverno/apply/command.go +++ b/pkg/kyverno/apply/command.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io/ioutil" + "os" "regexp" "time" @@ -68,7 +69,8 @@ func Command() *cobra.Command { for _, policy := range policies { err := policy2.Validate(utils.MarshalPolicy(*policy), nil, true, openAPIController) if err != nil { - return sanitizedError.New(fmt.Sprintf("Policy %v is not valid", policy.Name)) + fmt.Printf("Policy %v is not valid\n", policy.Name) + os.Exit(3) } if policyHasVariables(*policy) { return sanitizedError.New(fmt.Sprintf("Policy %v is not valid - 'apply' does not support policies with variables", policy.Name)) @@ -241,7 +243,7 @@ func getResource(path string) ([]*unstructured.Unstructured, error) { } func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unstructured) error { - + responseError := false fmt.Printf("\n\nApplying Policy %s on Resource %s/%s/%s\n", policy.Name, resource.GetNamespace(), resource.GetKind(), resource.GetName()) mutateResponse := engine.Mutate(engine.PolicyContext{Policy: *policy, NewResource: *resource}) @@ -252,6 +254,7 @@ func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unst fmt.Printf("\n%d. %s", i+1, r.Message) } fmt.Printf("\n\n") + responseError = true } else { if len(mutateResponse.PolicyResponse.Rules) > 0 { fmt.Printf("\n\nMutation:") @@ -274,6 +277,7 @@ func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unst fmt.Printf("\n%d. %s", i+1, r.Message) } fmt.Printf("\n\n") + responseError = true } else { if len(validateResponse.PolicyResponse.Rules) > 0 { fmt.Printf("\n\nValidation:") @@ -302,9 +306,13 @@ func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unst fmt.Printf("\n%d. %s", i+1, r.Message) } fmt.Printf("\n\n") + responseError = true } } + if responseError == true{ + os.Exit(1) + } return nil } diff --git a/pkg/kyverno/common/common.go b/pkg/kyverno/common/common.go index 4744f51d3e..050bca3ea0 100644 --- a/pkg/kyverno/common/common.go +++ b/pkg/kyverno/common/common.go @@ -57,7 +57,8 @@ func GetPolicies(paths []string) (policies []*v1.ClusterPolicy, error error) { } if errString != "" { - return nil, sanitizedError.New(("falied to extract policies")) + fmt.Println("falied to extract policies") + os.Exit(2) } policies = append(policies, getPolicies...) diff --git a/pkg/kyverno/validate/command.go b/pkg/kyverno/validate/command.go index a5ff93c937..a1b6f6eeaf 100644 --- a/pkg/kyverno/validate/command.go +++ b/pkg/kyverno/validate/command.go @@ -2,6 +2,7 @@ package validate import ( "fmt" + "os" "github.com/nirmata/kyverno/pkg/utils" @@ -34,15 +35,20 @@ func Command() *cobra.Command { return err } + invalidPolicyFound := false for _, policy := range policies { err = policyvalidate.Validate(utils.MarshalPolicy(*policy), nil, true, openAPIController) if err != nil { fmt.Println("Policy " + policy.Name + " is invalid") + invalidPolicyFound = true } else { fmt.Println("Policy " + policy.Name + " is valid") } } + if invalidPolicyFound == true { + os.Exit(1) + } return nil }, }