From c97b3ce5b0dbe6401f66e784079e7389a65aad5d Mon Sep 17 00:00:00 2001 From: Shuting Zhao Date: Mon, 6 Jan 2020 19:24:24 -0800 Subject: [PATCH] fetch annotation from resource annotation map --- pkg/webhooks/annotations.go | 14 +++++++++++++ pkg/webhooks/mutation.go | 16 +++----------- pkg/webhooks/server.go | 42 ++++++++++++++++++++++++------------- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/pkg/webhooks/annotations.go b/pkg/webhooks/annotations.go index 610617b8a8..21ed21414d 100644 --- a/pkg/webhooks/annotations.go +++ b/pkg/webhooks/annotations.go @@ -5,7 +5,9 @@ import ( jsonpatch "github.com/evanphx/json-patch" "github.com/golang/glog" + "github.com/nirmata/kyverno/pkg/engine" "github.com/nirmata/kyverno/pkg/engine/response" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) const ( @@ -143,3 +145,15 @@ func annotationFromPolicyResponse(policyResponse response.PolicyResponse) []rule return rulePatches } + +// checkPodTemplateAnn checks if a Pod has annotation "pod-policies.kyverno.io/autogen-applied" +func checkPodTemplateAnn(resource unstructured.Unstructured) bool { + if resource.GetKind() == "Pod" { + ann := resource.GetAnnotations() + if _, ok := ann[engine.PodTemplateAnnotation]; ok { + return true + } + } + + return false +} diff --git a/pkg/webhooks/mutation.go b/pkg/webhooks/mutation.go index 531a75e12d..a93fa38b14 100644 --- a/pkg/webhooks/mutation.go +++ b/pkg/webhooks/mutation.go @@ -9,11 +9,11 @@ import ( policyctr "github.com/nirmata/kyverno/pkg/policy" "github.com/nirmata/kyverno/pkg/utils" v1beta1 "k8s.io/api/admission/v1beta1" - "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) // HandleMutation handles mutating webhook admission request -func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, policies []kyverno.ClusterPolicy, roles, clusterRoles []string) (bool, []byte, string) { +func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, resource unstructured.Unstructured, policies []kyverno.ClusterPolicy, roles, clusterRoles []string) (bool, []byte, string) { glog.V(4).Infof("Receive request in mutating webhook: Kind=%s, Namespace=%s Name=%s UID=%s patchOperation=%s", request.Kind.Kind, request.Namespace, request.Name, request.UID, request.Operation) @@ -51,17 +51,7 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, polic ws.policyStatus.SendStat(stat) } } - // convert RAW to unstructured - resource, err := engine.ConvertToUnstructured(request.Object.Raw) - if err != nil { - //TODO: skip applying the amiddions control ? - glog.Errorf("unable to convert raw resource to unstructured: %v", err) - return true, nil, "" - } - // if not then set it from the api request - resource.SetGroupVersionKind(schema.GroupVersionKind{Group: request.Kind.Group, Version: request.Kind.Version, Kind: request.Kind.Kind}) - resource.SetNamespace(request.Namespace) var engineResponses []response.EngineResponse // build context ctx := context.NewContext() @@ -70,7 +60,7 @@ func (ws *WebhookServer) HandleMutation(request *v1beta1.AdmissionRequest, polic ctx.AddUserInfo(request.UserInfo) policyContext := engine.PolicyContext{ - NewResource: *resource, + NewResource: resource, Context: ctx, AdmissionInfo: engine.RequestInfo{ Roles: roles, diff --git a/pkg/webhooks/server.go b/pkg/webhooks/server.go index 148265de3f..a2e1b27fbb 100644 --- a/pkg/webhooks/server.go +++ b/pkg/webhooks/server.go @@ -1,7 +1,6 @@ package webhooks import ( - "bytes" "context" "crypto/tls" "encoding/json" @@ -28,6 +27,7 @@ import ( "github.com/nirmata/kyverno/pkg/webhookconfig" v1beta1 "k8s.io/api/admission/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" rbacinformer "k8s.io/client-go/informers/rbac/v1" rbaclister "k8s.io/client-go/listers/rbac/v1" "k8s.io/client-go/tools/cache" @@ -187,18 +187,6 @@ func (ws *WebhookServer) serve(w http.ResponseWriter, r *http.Request) { } func (ws *WebhookServer) handleAdmissionRequest(request *v1beta1.AdmissionRequest) *v1beta1.AdmissionResponse { - if request.Kind.Kind == "Pod" { - if bytes.Contains(request.Object.Raw, []byte(engine.PodTemplateAnnotation)) { - glog.V(4).Infof("Policies already processed on pod controllers, skip processing policy on Pod UID=%s", request.UID) - return &v1beta1.AdmissionResponse{ - Allowed: true, - Result: &metav1.Status{ - Status: "Success", - }, - } - } - } - policies, err := ws.pMetaStore.LookUp(request.Kind.Kind, request.Namespace) if err != nil { // Unable to connect to policy Lister to access policies @@ -220,8 +208,34 @@ func (ws *WebhookServer) handleAdmissionRequest(request *v1beta1.AdmissionReques } glog.V(4).Infof("Time: webhook GetRoleRef %v", time.Since(startTime)) + // convert RAW to unstructured + resource, err := engine.ConvertToUnstructured(request.Object.Raw) + if err != nil { + msg := fmt.Sprintf("unable to convert raw resource to unstructured: %v", err) + glog.Errorf(msg) + return &v1beta1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Status: "Failure", + Message: msg, + }, + } + } + + // if not then set it from the api request + resource.SetGroupVersionKind(schema.GroupVersionKind{Group: request.Kind.Group, Version: request.Kind.Version, Kind: request.Kind.Kind}) + resource.SetNamespace(request.Namespace) + if checkPodTemplateAnn(*resource) { + return &v1beta1.AdmissionResponse{ + Allowed: true, + Result: &metav1.Status{ + Status: "Success", + }, + } + } + // MUTATION - ok, patches, msg := ws.HandleMutation(request, policies, roles, clusterRoles) + ok, patches, msg := ws.HandleMutation(request, *resource, policies, roles, clusterRoles) if !ok { glog.V(4).Infof("Deny admission request: %v/%s/%s", request.Kind, request.Namespace, request.Name) return &v1beta1.AdmissionResponse{