From 4535f432833efaeca83edb22ecad9a52d9e9bc36 Mon Sep 17 00:00:00 2001 From: Yuvraj <10830562+evalsocket@users.noreply.github.com> Date: Mon, 13 Jul 2020 13:42:11 -0700 Subject: [PATCH] Added Synchronize flag in Generate Request (#980) * fix Synchronize flag issue --- definitions/manifest/deployment.yaml | 10 ++++- pkg/api/kyverno/v1/types.go | 6 +-- pkg/engine/response/response.go | 1 + pkg/generate/generate.go | 5 +-- pkg/webhooks/generation.go | 1 + pkg/webhooks/server.go | 39 +++++++++++-------- .../best_practices/add_network_policy.yaml | 1 + samples/best_practices/add_ns_quota.yaml | 2 + 8 files changed, 39 insertions(+), 26 deletions(-) diff --git a/definitions/manifest/deployment.yaml b/definitions/manifest/deployment.yaml index 1a197e0d3d..1a99fd9381 100644 --- a/definitions/manifest/deployment.yaml +++ b/definitions/manifest/deployment.yaml @@ -19,10 +19,10 @@ spec: serviceAccountName: kyverno-service-account initContainers: - name: kyverno-pre - image: nirmata/kyvernopre:v1.1.6 + image: nirmata/kyvernopre:v1.1.7-rc2 containers: - name: kyverno - image: nirmata/kyverno:v1.1.6 + image: nirmata/kyverno:v1.1.7-rc2 imagePullPolicy: Always args: - "--filterK8Resources=[Event,*,*][*,kube-system,*][*,kube-public,*][*,kube-node-lease,*][Node,*,*][APIService,*,*][TokenReview,*,*][SubjectAccessReview,*,*][*,kyverno,*][Binding,*,*][ReplicaSet,*,*]" @@ -36,6 +36,12 @@ spec: env: - name: INIT_CONFIG value: init-config + - name: KYVERNO_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: KYVERNO_SVC + value: kyverno-svc resources: requests: memory: "50Mi" diff --git a/pkg/api/kyverno/v1/types.go b/pkg/api/kyverno/v1/types.go index c4b4f3b8d8..3150d603cd 100644 --- a/pkg/api/kyverno/v1/types.go +++ b/pkg/api/kyverno/v1/types.go @@ -19,9 +19,9 @@ type GenerateRequest struct { //GenerateRequestSpec stores the request specification type GenerateRequestSpec struct { - Policy string `json:"policy"` - Resource ResourceSpec `json:"resource"` - Context GenerateRequestContext `json:"context"` + Policy string `json:"policy"` + Resource ResourceSpec `json:"resource"` + Context GenerateRequestContext `json:"context"` } //GenerateRequestContext stores the context to be shared diff --git a/pkg/engine/response/response.go b/pkg/engine/response/response.go index eeb37dd2cb..6f866df272 100644 --- a/pkg/engine/response/response.go +++ b/pkg/engine/response/response.go @@ -13,6 +13,7 @@ type EngineResponse struct { PatchedResource unstructured.Unstructured // Policy Response PolicyResponse PolicyResponse + } //PolicyResponse policy application response diff --git a/pkg/generate/generate.go b/pkg/generate/generate.go index 6c6090595e..20580dfa59 100644 --- a/pkg/generate/generate.go +++ b/pkg/generate/generate.go @@ -294,9 +294,8 @@ func applyRule(log logr.Logger, client *dclient.Client, rule kyverno.Rule, resou } else if mode == Update { label := newResource.GetLabels() - if label != nil { - if label["app.kubernetes.io/synchronize"] == "enable" { + if rule.Generation.Synchronize { logger.V(4).Info("updating existing resource") // Update the resource _, err := client.UpdateResource(genKind, genNamespace, newResource, false) @@ -313,9 +312,7 @@ func applyRule(log logr.Logger, client *dclient.Client, rule kyverno.Rule, resou } else { logger.V(4).Info("Synchronize resource is disabled") } - } - return newGenResource, nil } diff --git a/pkg/webhooks/generation.go b/pkg/webhooks/generation.go index 8d57d76543..8e31a4ed17 100644 --- a/pkg/webhooks/generation.go +++ b/pkg/webhooks/generation.go @@ -90,6 +90,7 @@ func applyGenerateRequest(gnGenerator generate.GenerateRequests, userRequestInfo } func transform(userRequestInfo kyverno.RequestInfo, er response.EngineResponse) kyverno.GenerateRequestSpec { + gr := kyverno.GenerateRequestSpec{ Policy: er.PolicyResponse.Policy, Resource: kyverno.ResourceSpec{ diff --git a/pkg/webhooks/server.go b/pkg/webhooks/server.go index 8e064a7988..c45954ae9c 100644 --- a/pkg/webhooks/server.go +++ b/pkg/webhooks/server.go @@ -556,31 +556,36 @@ func (ws *WebhookServer) bodyToAdmissionReview(request *http.Request, writer htt func (ws *WebhookServer) excludeKyvernoResources(request *v1beta1.AdmissionRequest) error { logger := ws.log.WithName("resourceValidation").WithValues("uid", request.UID, "kind", request.Kind.Kind, "namespace", request.Namespace, "name", request.Name, "operation", request.Operation) - checked, err := userinfo.IsRoleAuthorize(ws.rbLister, ws.crbLister, ws.rLister, ws.crLister, request) + var resource *unstructured.Unstructured + var err error + var isManagedResourceCheck bool + if request.Operation == v1beta1.Delete { + resource, err = enginutils.ConvertToUnstructured(request.OldObject.Raw) + isManagedResourceCheck = true + } else if request.Operation == v1beta1.Update { + resource, err = enginutils.ConvertToUnstructured(request.Object.Raw) + isManagedResourceCheck = true + } if err != nil { - logger.Error(err, "failed to get RBAC infromation for request") + logger.Error(err, "failed to convert object resource to unstructured format") + return err } - if !checked { - // convert RAW to unstructured - var resource *unstructured.Unstructured - if request.Operation == v1beta1.Delete { - resource, err = enginutils.ConvertToUnstructured(request.OldObject.Raw) - } else { - resource, err = enginutils.ConvertToUnstructured(request.Object.Raw) - } - if err != nil { - logger.Error(err, "failed to convert RAR resource to unstructured format") - return err - } - + if isManagedResourceCheck { labels := resource.GetLabels() if labels != nil { if labels["app.kubernetes.io/managed-by"] == "kyverno" && labels["app.kubernetes.io/synchronize"] == "enable" { - return fmt.Errorf("Resource is managed by Kyverno, can't be changed manually. You can edit generate policy to update this resource") + isAuthorized, err := userinfo.IsRoleAuthorize(ws.rbLister, ws.crbLister, ws.rLister, ws.crLister, request) + if err != nil { + return fmt.Errorf("failed to get RBAC infromation for request %v",err) + } + if !isAuthorized { + // convert RAW to unstructured + return fmt.Errorf("Resource is managed by Kyverno, can't be changed manually. You can edit generate policy to update this resource") + } } } - } + return nil } diff --git a/samples/best_practices/add_network_policy.yaml b/samples/best_practices/add_network_policy.yaml index d195330afa..df55267384 100644 --- a/samples/best_practices/add_network_policy.yaml +++ b/samples/best_practices/add_network_policy.yaml @@ -22,6 +22,7 @@ spec: kind: NetworkPolicy name: default-deny-ingress namespace: "{{request.object.metadata.name}}" + synchronize : true data: spec: # select all pods in the namespace diff --git a/samples/best_practices/add_ns_quota.yaml b/samples/best_practices/add_ns_quota.yaml index d8a1f147d4..be93dacc23 100644 --- a/samples/best_practices/add_ns_quota.yaml +++ b/samples/best_practices/add_ns_quota.yaml @@ -17,6 +17,7 @@ spec: generate: kind: ResourceQuota name: default-resourcequota + synchronize : true namespace: "{{request.object.metadata.name}}" data: spec: @@ -33,6 +34,7 @@ spec: generate: kind: LimitRange name: default-limitrange + synchronize : true namespace: "{{request.object.metadata.name}}" data: spec: