1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-15 12:17:56 +00:00

improve CLI validation reports

This commit is contained in:
Jim Bugwadia 2020-08-18 21:03:00 -07:00
parent 5a68653749
commit fc6da9c9e6
3 changed files with 92 additions and 67 deletions

6
go.sum
View file

@ -45,6 +45,7 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko
github.com/Shopify/sarama v1.24.1/go.mod h1:fGP8eQ6PugKEI0iUETYYtnP6d1pH/bdDMTel1X5ajsU= github.com/Shopify/sarama v1.24.1/go.mod h1:fGP8eQ6PugKEI0iUETYYtnP6d1pH/bdDMTel1X5ajsU=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/ahmetb/gen-crd-api-reference-docs v0.2.0 h1:YI/cAcRdNAHArfhGKcmCY5qMa32k/UyCZagLgabC5JY= github.com/ahmetb/gen-crd-api-reference-docs v0.2.0 h1:YI/cAcRdNAHArfhGKcmCY5qMa32k/UyCZagLgabC5JY=
@ -184,6 +185,7 @@ github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
@ -663,6 +665,7 @@ github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qo
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg= github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-ieproxy v0.0.0-20190805055040-f9202b1cfdeb/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190805055040-f9202b1cfdeb/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
@ -671,6 +674,7 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
@ -818,6 +822,7 @@ github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4do
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20190704165056-9c2d0518ed81/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20190704165056-9c2d0518ed81/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8=
github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.0.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.0.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@ -834,6 +839,7 @@ github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIH
github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4= github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4=
github.com/santhosh-tekuri/jsonschema/v2 v2.1.0/go.mod h1:yzJzKUGV4RbWqWIBBP4wSOBqavX5saE02yirLS0OTyg= github.com/santhosh-tekuri/jsonschema/v2 v2.1.0/go.mod h1:yzJzKUGV4RbWqWIBBP4wSOBqavX5saE02yirLS0OTyg=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/secure-io/sio-go v0.3.0 h1:QKGb6rGJeiExac9wSWxnWPYo8O8OFN7lxXQvHshX6vo=
github.com/secure-io/sio-go v0.3.0/go.mod h1:D3KmXgKETffyYxBdFRN+Hpd2WzhzqS0EQwT3XWsAcBU= github.com/secure-io/sio-go v0.3.0/go.mod h1:D3KmXgKETffyYxBdFRN+Hpd2WzhzqS0EQwT3XWsAcBU=
github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do= github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do=
github.com/segmentio/analytics-go v3.0.1+incompatible/go.mod h1:C7CYBtQWk4vRk2RyLu0qOcbHJ18E3F1HV2C/8JvKN48= github.com/segmentio/analytics-go v3.0.1+incompatible/go.mod h1:C7CYBtQWk4vRk2RyLu0qOcbHJ18E3F1HV2C/8JvKN48=

View file

@ -37,17 +37,26 @@ import (
log "sigs.k8s.io/controller-runtime/pkg/log" log "sigs.k8s.io/controller-runtime/pkg/log"
) )
type resultCounts struct {
pass int
fail int
warn int
error int
skip int
}
func Command() *cobra.Command { func Command() *cobra.Command {
var cmd *cobra.Command var cmd *cobra.Command
var resourcePaths []string var resourcePaths []string
var cluster bool var cluster bool
var mutatelogPath string var mutateLogPath string
kubernetesConfig := genericclioptions.NewConfigFlags(true) kubernetesConfig := genericclioptions.NewConfigFlags(true)
cmd = &cobra.Command{ cmd = &cobra.Command{
Use: "apply", Use: "apply",
Short: "Applies policies on resources", Short: "applies policies on resources",
Example: fmt.Sprintf("To apply on a resource:\nkyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --resource=/path/to/resource1 --resource=/path/to/resource2\n\nTo apply on a cluster\nkyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --cluster"), Example: fmt.Sprintf("To apply on a resource:\nkyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --resource=/path/to/resource1 --resource=/path/to/resource2\n\nTo apply on a cluster\nkyverno apply /path/to/policy.yaml /path/to/folderOfPolicies --cluster"),
RunE: func(cmd *cobra.Command, policyPaths []string) (err error) { RunE: func(cmd *cobra.Command, policyPaths []string) (err error) {
defer func() { defer func() {
@ -60,12 +69,12 @@ func Command() *cobra.Command {
}() }()
if len(resourcePaths) == 0 && !cluster { if len(resourcePaths) == 0 && !cluster {
return sanitizedError.NewWithError("resource file or cluster required", err) return sanitizedError.NewWithError(fmt.Sprintf("resource file(s) or cluster required"), err)
} }
var mutatelogPathIsDir bool var mutatelogPathIsDir bool
if mutatelogPath != "" { if mutateLogPath != "" {
spath := strings.Split(mutatelogPath, "/") spath := strings.Split(mutateLogPath, "/")
sfileName := strings.Split(spath[len(spath)-1], ".") sfileName := strings.Split(spath[len(spath)-1], ".")
if sfileName[len(sfileName)-1] == "yml" || sfileName[len(sfileName)-1] == "yaml" { if sfileName[len(sfileName)-1] == "yml" || sfileName[len(sfileName)-1] == "yaml" {
mutatelogPathIsDir = false mutatelogPathIsDir = false
@ -73,7 +82,7 @@ func Command() *cobra.Command {
mutatelogPathIsDir = true mutatelogPathIsDir = true
} }
err = createFileOrFolder(mutatelogPath, mutatelogPathIsDir) err = createFileOrFolder(mutateLogPath, mutatelogPathIsDir)
if err != nil { if err != nil {
if !sanitizedError.IsErrorSanitized(err) { if !sanitizedError.IsErrorSanitized(err) {
return sanitizedError.NewWithError("failed to create file/folder.", err) return sanitizedError.NewWithError("failed to create file/folder.", err)
@ -90,18 +99,6 @@ func Command() *cobra.Command {
return err return err
} }
for _, policy := range policies {
err := policy2.Validate(utils.MarshalPolicy(*policy), nil, true, openAPIController)
if err != nil {
fmt.Printf("Policy %v is not valid: %v\n", policy.Name, err)
os.Exit(1)
}
if common.PolicyHasVariables(*policy) {
return sanitizedError.NewWithError(fmt.Sprintf("invalid policy %s. 'apply' does not support policies with variables", policy.Name), err)
}
}
var dClient *client.Client var dClient *client.Client
if cluster { if cluster {
restConfig, err := kubernetesConfig.ToRESTConfig() restConfig, err := kubernetesConfig.ToRESTConfig()
@ -119,31 +116,61 @@ func Command() *cobra.Command {
return sanitizedError.NewWithError("failed to load resources", err) return sanitizedError.NewWithError("failed to load resources", err)
} }
newPolicies, err := mutatePolices(policies) mutatedPolicies, err := mutatePolices(policies)
if err != nil { msgPolicies := "1 policy"
return sanitizedError.NewWithError("failed to mutate policy", err) if len(mutatedPolicies) > 1 {
msgPolicies = fmt.Sprintf("%d policies", len(policies))
} }
for i, policy := range newPolicies { msgResources := "1 resource"
for j, resource := range resources { if len(resources) > 1 {
if !(j == 0 && i == 0) { msgResources = fmt.Sprintf("%d resources", len(resources))
fmt.Printf("\n\n==========================================================================================\n") }
}
err = applyPolicyOnResource(policy, resource, mutatelogPath, mutatelogPathIsDir) fmt.Printf("\napplying %s to %s \n", msgPolicies, msgResources)
if len(mutatedPolicies) == 0 || len(resources) == 0 {
return
}
rc := &resultCounts{}
for _, policy := range mutatedPolicies {
err := policy2.Validate(utils.MarshalPolicy(*policy), nil, true, openAPIController)
if err != nil {
rc.skip += len(resources)
fmt.Printf("\nskipping policy %v as it is not valid: %v\n", policy.Name, err)
continue
}
if common.PolicyHasVariables(*policy) {
rc.skip += len(resources)
fmt.Printf("\nskipping policy %s as policies with variables are not supported\n", policy.Name)
continue
}
for _, resource := range resources {
applyPolicyOnResource(policy, resource, rc)
if err != nil { if err != nil {
return sanitizedError.NewWithError(fmt.Errorf("failed to apply policy %v on resource %v", policy.Name, resource.GetName()).Error(), err) return sanitizedError.NewWithError(fmt.Errorf("failed to apply policy %v on resource %v", policy.Name, resource.GetName()).Error(), err)
} }
} }
} }
fmt.Printf("\npass: %d, fail: %d, warn: %d, error: %d, skip: %d \n",
rc.pass, rc.fail, rc.warn, rc.error, rc.skip)
if rc.fail > 0 || rc.error > 0 {
os.Exit(1)
}
return nil return nil
}, },
} }
cmd.Flags().StringArrayVarP(&resourcePaths, "resource", "r", []string{}, "Path to resource files") cmd.Flags().StringArrayVarP(&resourcePaths, "resource", "r", []string{}, "Path to resource files")
cmd.Flags().BoolVarP(&cluster, "cluster", "c", false, "Checks if policies should be applied to cluster in the current context") cmd.Flags().BoolVarP(&cluster, "cluster", "c", false, "Checks if policies should be applied to cluster in the current context")
cmd.Flags().StringVarP(&mutatelogPath, "output", "o", "", "Prints the mutated resources in provided file/directory") cmd.Flags().StringVarP(&mutateLogPath, "output", "o", "", "Prints the mutated resources in provided file/directory")
return cmd return cmd
} }
@ -273,55 +300,45 @@ func getResource(path string) ([]*unstructured.Unstructured, error) {
} }
// applyPolicyOnResource - function to apply policy on resource // applyPolicyOnResource - function to apply policy on resource
func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unstructured, mutatelogPath string, mutatelogPathIsDir bool) error { func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unstructured, rc *resultCounts) {
fmt.Printf("\n\nApplying Policy %s on Resource %s/%s/%s\n", policy.Name, resource.GetNamespace(), resource.GetKind(), resource.GetName()) responseError := false
resPath := fmt.Sprintf("%s/%s/%s", resource.GetNamespace(), resource.GetKind(), resource.GetName())
log.Log.V(3).Info("applying policy on resource", "policy", policy.Name, "resource", resPath)
mutateResponse := engine.Mutate(engine.PolicyContext{Policy: *policy, NewResource: *resource}) mutateResponse := engine.Mutate(engine.PolicyContext{Policy: *policy, NewResource: *resource})
if !mutateResponse.IsSuccessful() { if !mutateResponse.IsSuccessful() {
fmt.Printf("\n\nMutation:") fmt.Printf("Failed to apply mutate policy %s -> resource %s", policy.Name, resPath)
fmt.Printf("\nFailed to apply mutation")
for i, r := range mutateResponse.PolicyResponse.Rules { for i, r := range mutateResponse.PolicyResponse.Rules {
fmt.Printf("\n%d. %s", i+1, r.Message) fmt.Printf("\n%d. %s", i+1, r.Message)
} }
fmt.Printf("\n\n") responseError = true
} else { } else {
if len(mutateResponse.PolicyResponse.Rules) > 0 { if len(mutateResponse.PolicyResponse.Rules) > 0 {
yamlEncodedResource, err := yamlv2.Marshal(mutateResponse.PatchedResource.Object) yamlEncodedResource, err := yamlv2.Marshal(mutateResponse.PatchedResource.Object)
if err != nil { if err != nil {
return err rc.error++
} }
if mutatelogPath == "" { mutatedResource := string(yamlEncodedResource)
fmt.Printf("\n\nMutation:\nMutation has been applied succesfully") if len(strings.TrimSpace(mutatedResource)) > 0 {
fmt.Printf("\n\n" + string(yamlEncodedResource)) fmt.Printf("mutate policy %s applied to %s:", policy.Name, resPath)
fmt.Printf("\n\n") fmt.Printf("\n" + mutatedResource)
} else { fmt.Printf("\n")
err := printMutatedOutput(mutatelogPath, mutatelogPathIsDir, string(yamlEncodedResource), resource.GetName()+"-mutated")
if err != nil {
return sanitizedError.NewWithError("failed to print mutated result", err)
}
fmt.Printf("\n\nMutation:\nMutation has been applied succesfully. Check the files.")
} }
} else {
fmt.Printf("\n\nMutation:\nMutation skipped. Resource not matches the policy")
} }
} }
validateResponse := engine.Validate(engine.PolicyContext{Policy: *policy, NewResource: mutateResponse.PatchedResource}) validateResponse := engine.Validate(engine.PolicyContext{Policy: *policy, NewResource: mutateResponse.PatchedResource})
if !validateResponse.IsSuccessful() { if !validateResponse.IsSuccessful() {
fmt.Printf("\n\nValidation:") fmt.Printf("\npolicy %s -> resource %s failed: \n", policy.Name, resPath)
fmt.Printf("\nResource is invalid")
for i, r := range validateResponse.PolicyResponse.Rules { for i, r := range validateResponse.PolicyResponse.Rules {
fmt.Printf("\n%d. %s", i+1, r.Message) if !r.Success {
} fmt.Printf("%d. %s: %s \n", i+1, r.Name, r.Message)
fmt.Printf("\n\n") }
} else {
if len(validateResponse.PolicyResponse.Rules) > 0 {
fmt.Printf("\n\nValidation:")
fmt.Printf("\nResource is valid")
fmt.Printf("\n\n")
} }
responseError = true
} }
var policyHasGenerate bool var policyHasGenerate bool
@ -334,20 +351,22 @@ func applyPolicyOnResource(policy *v1.ClusterPolicy, resource *unstructured.Unst
if policyHasGenerate { if policyHasGenerate {
generateResponse := engine.Generate(engine.PolicyContext{Policy: *policy, NewResource: *resource}) generateResponse := engine.Generate(engine.PolicyContext{Policy: *policy, NewResource: *resource})
if len(generateResponse.PolicyResponse.Rules) > 0 { if len(generateResponse.PolicyResponse.Rules) > 0 {
fmt.Printf("\n\nGenerate:") log.Log.V(3).Info("generate resource is valid", "policy", policy.Name, "resource", resPath)
fmt.Printf("\nResource is valid")
fmt.Printf("\n\n")
} else { } else {
fmt.Printf("\n\nGenerate:") fmt.Printf("generate policy %s resource %s is invalid \n", policy.Name, resPath)
fmt.Printf("\nResource is invalid")
for i, r := range generateResponse.PolicyResponse.Rules { for i, r := range generateResponse.PolicyResponse.Rules {
fmt.Printf("\n%d. %s", i+1, r.Message) fmt.Printf("%d. %s \b", i+1, r.Message)
} }
fmt.Printf("\n\n")
responseError = true
} }
} }
return nil if responseError == true {
rc.fail++
} else {
rc.pass++
}
} }
// mutatePolicies - function to apply mutation on policies // mutatePolicies - function to apply mutation on policies
@ -394,7 +413,7 @@ func printMutatedOutput(mutatelogPath string, mutatelogPathIsDir bool, yaml stri
return nil return nil
} }
// createFileOrFolder - creating file or folder accoring to path provided // createFileOrFolder - creating file or folder according to path provided
func createFileOrFolder(mutatelogPath string, mutatelogPathIsDir bool) error { func createFileOrFolder(mutatelogPath string, mutatelogPathIsDir bool) error {
mutatelogPath = filepath.Clean(mutatelogPath) mutatelogPath = filepath.Clean(mutatelogPath)
_, err := os.Stat(mutatelogPath) _, err := os.Stat(mutatelogPath)

View file

@ -61,7 +61,7 @@ func GetPolicies(paths []string) (policies []*v1.ClusterPolicy, error error) {
} }
if errString != "" { if errString != "" {
fmt.Println("falied to extract policies") fmt.Println("failed to extract policies: %s", errString)
os.Exit(2) os.Exit(2)
} }