From f0fab9499e7144ad6d28d0aa5e37fd3ca2d65d32 Mon Sep 17 00:00:00 2001 From: NoSkillGirl Date: Fri, 10 Jul 2020 14:56:07 +0530 Subject: [PATCH] temp --- go.mod | 4 +- go.sum | 8 ++ pkg/api/kyverno/v1/utils.go | 4 +- pkg/kyverno/apply/command.go | 42 ++++++++++- pkg/webhooks/policymutation.go | 51 ++++++++++--- .../best_practices/disallow_latest_tag.yaml | 75 +++++++++++++++++++ 6 files changed, 170 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 4534fef0c4..1805cd4306 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,10 @@ module github.com/nirmata/kyverno go 1.13 require ( + github.com/cameront/go-jsonpatch v0.0.0-20180223123257-a8710867776e github.com/cenkalti/backoff v2.2.1+incompatible github.com/evanphx/json-patch v4.5.0+incompatible + github.com/evanphx/json-patch/v5 v5.0.0 // indirect github.com/go-logr/logr v0.1.0 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 // indirect @@ -16,7 +18,7 @@ require ( github.com/julienschmidt/httprouter v1.3.0 github.com/minio/minio v0.0.0-20200114012931-30922148fbb5 github.com/ory/go-acc v0.2.1 // indirect - github.com/pkg/errors v0.8.1 + github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/common v0.4.1 github.com/rogpeppe/godef v1.1.2 // indirect github.com/spf13/cobra v0.0.5 diff --git a/go.sum b/go.sum index a05d684930..0589278503 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,8 @@ github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17 github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/cameront/go-jsonpatch v0.0.0-20180223123257-a8710867776e h1:6c3+GQuYUWljNcReOg4gxMUss9Gjll+5Y9vqDM+ILy8= +github.com/cameront/go-jsonpatch v0.0.0-20180223123257-a8710867776e/go.mod h1:kdPJxKAfR3ZdD+MWYorN1oTdV9+qwJy9jO/0meJmcxU= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -137,6 +139,8 @@ github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6 github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M= github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.0.0 h1:dKTrUeykyQwKb/kx7Z+4ukDs6l+4L41HqG1XHnhX7WE= +github.com/evanphx/json-patch/v5 v5.0.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= @@ -503,6 +507,7 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ= github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmoiron/sqlx v0.0.0-20180614180643-0dae4fefe7c0/go.mod h1:IiEW3SEiiErVyFdH8NTuWjSifiEQKUoyK3LNqr2kCHU= @@ -698,6 +703,8 @@ github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -827,6 +834,7 @@ github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= diff --git a/pkg/api/kyverno/v1/utils.go b/pkg/api/kyverno/v1/utils.go index b76363b447..4f091f8880 100644 --- a/pkg/api/kyverno/v1/utils.go +++ b/pkg/api/kyverno/v1/utils.go @@ -1,6 +1,8 @@ package v1 -import "reflect" +import ( + "reflect" +) func (p *ClusterPolicy) HasAutoGenAnnotation() bool { annotations := p.GetAnnotations() diff --git a/pkg/kyverno/apply/command.go b/pkg/kyverno/apply/command.go index bd4c1fc660..2b376587dd 100644 --- a/pkg/kyverno/apply/command.go +++ b/pkg/kyverno/apply/command.go @@ -33,6 +33,9 @@ import ( "k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/client-go/kubernetes/scheme" log "sigs.k8s.io/controller-runtime/pkg/log" + + jsonpatch "github.com/evanphx/json-patch" + "github.com/nirmata/kyverno/pkg/webhooks" ) func Command() *cobra.Command { @@ -69,7 +72,7 @@ func Command() *cobra.Command { 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(3) + os.Exit(1) } if common.PolicyHasVariables(*policy) { @@ -94,6 +97,43 @@ func Command() *cobra.Command { return sanitizedError.NewWithError("failed to load resources", err) } + for _, policy := range policies { + res2B, _ := json.MarshalIndent(policy, "", " ") + fmt.Println("res2B: ", string(res2B)) + + patches, _ := webhooks.GenerateJSONPatchesForDefaults(policy, nil) + + type jsonPatch struct { + Path string `json:"path"` + Op string `json:"op"` + Value interface{} `json:"value"` + } + + var jsonPatches []jsonPatch + json.Unmarshal(patches, &jsonPatches) + patch, err := jsonpatch.DecodePatch(patches) + if err != nil { + panic(err) + } + + policyBytes, _ := json.Marshal(policy) + + modifiedPolicy, err := patch.Apply(policyBytes) + if err != nil { + panic(err) + } + + var p v1.ClusterPolicy + json.Unmarshal(modifiedPolicy, &p) + + // policy = &p + + fmt.Println("======================================") + res2B, _ = json.MarshalIndent(policy, "", " ") + fmt.Println(string(res2B)) + + } + for i, policy := range policies { for j, resource := range resources { if !(j == 0 && i == 0) { diff --git a/pkg/webhooks/policymutation.go b/pkg/webhooks/policymutation.go index 926bd10fe5..b676ace93a 100644 --- a/pkg/webhooks/policymutation.go +++ b/pkg/webhooks/policymutation.go @@ -32,7 +32,10 @@ func (ws *WebhookServer) policyMutation(request *v1beta1.AdmissionRequest) *v1be } } // Generate JSON Patches for defaults - patches, updateMsgs := generateJSONPatchesForDefaults(policy, logger) + patches, updateMsgs := GenerateJSONPatchesForDefaults(policy, logger) + fmt.Println("---------------policyMutation----------------") + fmt.Println("patches: ", string(patches)) + fmt.Println("---------------------------------------------") if patches != nil { patchType := v1beta1.PatchTypeJSONPatch return &v1beta1.AdmissionResponse{ @@ -49,7 +52,8 @@ func (ws *WebhookServer) policyMutation(request *v1beta1.AdmissionRequest) *v1be } } -func generateJSONPatchesForDefaults(policy *kyverno.ClusterPolicy, log logr.Logger) ([]byte, []string) { +func GenerateJSONPatchesForDefaults(policy *kyverno.ClusterPolicy, log logr.Logger) ([]byte, []string) { + fmt.Println("-------------coming here in GenerateJSONPatchesForDefaults----------------") var patches [][]byte var updateMsgs []string @@ -70,7 +74,11 @@ func generateJSONPatchesForDefaults(policy *kyverno.ClusterPolicy, log logr.Logg var errMsgs []string for _, err := range errs { errMsgs = append(errMsgs, err.Error()) - log.Error(err, "failed to generate pod controller rule") + if log != nil { + log.Error(err, "failed to generate pod controller rule") + } else { + fmt.Println(err, " failed to generate pod controller rule") + } } updateMsgs = append(updateMsgs, strings.Join(errMsgs, ";")) } @@ -84,7 +92,9 @@ func defaultBackgroundFlag(policy *kyverno.ClusterPolicy, log logr.Logger) ([]by // set 'Background' flag to 'true' if not specified defaultVal := true if policy.Spec.Background == nil { - log.V(4).Info("setting default value", "spec.background", true) + if log != nil { + log.V(4).Info("setting default value", "spec.background", true) + } jsonPatch := struct { Path string `json:"path"` Op string `json:"op"` @@ -97,11 +107,17 @@ func defaultBackgroundFlag(policy *kyverno.ClusterPolicy, log logr.Logger) ([]by patchByte, err := json.Marshal(jsonPatch) if err != nil { - log.Error(err, "failed to set default value", "spec.background", true) + if log != nil { + log.Error(err, "failed to set default value", "spec.background", true) + } else { + fmt.Println(err, "failed to set default value", "spec.background") + } return nil, "" } - log.V(3).Info("generated JSON Patch to set default", "spec.background", true) + if log != nil { + log.V(3).Info("generated JSON Patch to set default", "spec.background", true) + } return patchByte, fmt.Sprintf("default 'Background' to '%s'", strconv.FormatBool(true)) } @@ -111,7 +127,10 @@ func defaultBackgroundFlag(policy *kyverno.ClusterPolicy, log logr.Logger) ([]by func defaultvalidationFailureAction(policy *kyverno.ClusterPolicy, log logr.Logger) ([]byte, string) { // set ValidationFailureAction to "audit" if not specified if policy.Spec.ValidationFailureAction == "" { - log.V(4).Info("setting defautl value", "spec.validationFailureAction", Audit) + if log != nil { + log.V(4).Info("setting defautl value", "spec.validationFailureAction", Audit) + } + jsonPatch := struct { Path string `json:"path"` Op string `json:"op"` @@ -124,11 +143,17 @@ func defaultvalidationFailureAction(policy *kyverno.ClusterPolicy, log logr.Logg patchByte, err := json.Marshal(jsonPatch) if err != nil { - log.Error(err, "failed to default value", "spec.validationFailureAction", Audit) + if log != nil { + log.Error(err, "failed to default value", "spec.validationFailureAction", Audit) + } + fmt.Println(err, "failed to default value", "spec.validationFailureAction", Audit) return nil, "" } - log.V(3).Info("generated JSON Patch to set default", "spec.validationFailureAction", Audit) + if log != nil { + log.V(3).Info("generated JSON Patch to set default", "spec.validationFailureAction", Audit) + } + return patchByte, fmt.Sprintf("default 'ValidationFailureAction' to '%s'", Audit) } @@ -165,7 +190,9 @@ func generatePodControllerRule(policy kyverno.ClusterPolicy, log logr.Logger) (p return nil, nil } - log.V(3).Info("auto generating rule for pod controllers", "controlers", controllers) + if log != nil { + log.V(3).Info("auto generating rule for pod controllers", "controlers", controllers) + } p, err := generateRulePatches(policy, controllers, log) patches = append(patches, p...) @@ -314,7 +341,9 @@ func generateRuleForControllers(rule kyverno.Rule, controllers string, log logr. if skipAutoGeneration { if match.ResourceDescription.Name != "" || match.ResourceDescription.Selector != nil || exclude.ResourceDescription.Name != "" || exclude.ResourceDescription.Selector != nil { - log.Info("skip generating rule on pod controllers: Name / Selector in resource decription may not be applicable.", "rule", rule.Name) + if log != nil { + log.Info("skip generating rule on pod controllers: Name / Selector in resource decription may not be applicable.", "rule", rule.Name) + } return kyvernoRule{} } if controllers == "all" { diff --git a/samples/best_practices/disallow_latest_tag.yaml b/samples/best_practices/disallow_latest_tag.yaml index 41812ed5f6..265a3e2134 100644 --- a/samples/best_practices/disallow_latest_tag.yaml +++ b/samples/best_practices/disallow_latest_tag.yaml @@ -31,3 +31,78 @@ spec: spec: containers: - image: "!*:latest" + + +# apiVersion: kyverno.io/v1 +# kind: ClusterPolicy +# metadata: +# annotations: +# pod-policies.kyverno.io/autogen-controllers: DaemonSet,Deployment,Job,StatefulSet +# policies.kyverno.io/category: Workload Isolation +# policies.kyverno.io/description: The ':latest' tag is mutable and can lead to +# unexpected errors if the image changes. A best practice is to use an immutable +# tag that maps to a specific version of an application pod. +# creationTimestamp: "2020-07-08T05:38:37Z" +# generation: 1 +# name: disallow-latest-tag +# resourceVersion: "553391" +# selfLink: /apis/kyverno.io/v1/clusterpolicies/disallow-latest-tag +# uid: 29f583d5-63f8-4494-98f8-0c06d55cdfe9 +# spec: +# background: true +# rules: +# - match: +# resources: +# kinds: +# - Pod +# name: require-image-tag +# validate: +# message: An image tag is required +# pattern: +# spec: +# containers: +# - image: '*:*' +# - match: +# resources: +# kinds: +# - Pod +# name: validate-image-tag +# validate: +# message: Using a mutable image tag e.g. 'latest' is not allowed +# pattern: +# spec: +# containers: +# - image: '!*:latest' +# - match: +# resources: +# kinds: +# - DaemonSet +# - Deployment +# - Job +# - StatefulSet +# name: autogen-require-image-tag +# validate: +# message: An image tag is required +# pattern: +# spec: +# template: +# spec: +# containers: +# - image: '*:*' +# - match: +# resources: +# kinds: +# - DaemonSet +# - Deployment +# - Job +# - StatefulSet +# name: autogen-validate-image-tag +# validate: +# message: Using a mutable image tag e.g. 'latest' is not allowed +# pattern: +# spec: +# template: +# spec: +# containers: +# - image: '!*:latest' +# validationFailureAction: audit \ No newline at end of file