From adca13c4f2eff22df35e25478a1cbfbd5f282bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Tue, 24 May 2022 16:41:17 +0200 Subject: [PATCH 1/4] refactor: add policy event listener in ur controller (#4012) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché (cherry picked from commit cd1fa030eefb33e45c10700c9d581a94d7c99db3) Signed-off-by: Charles-Edouard Brétéché From 836362ecdf4a4999f1fef78f50d403980ef07fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 25 May 2022 14:25:16 +0200 Subject: [PATCH 2/4] refactor: used typed admission request in ur MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché --- api/kyverno/v1beta1/updaterequest_types.go | 2 +- api/kyverno/v1beta1/zz_generated.deepcopy.go | 8 +- charts/kyverno/templates/crds.yaml | 119 +++++++++++- cmd/initContainer/main.go | 75 ++++---- config/crds/kyverno.io_updaterequests.yaml | 189 ++++++++++++++++++- config/install.yaml | 189 ++++++++++++++++++- config/install_debug.yaml | 189 ++++++++++++++++++- docs/crd/v1beta1/index.html | 4 +- pkg/background/common/context.go | 18 +- pkg/webhooks/resource/utils.go | 7 +- 10 files changed, 742 insertions(+), 58 deletions(-) diff --git a/api/kyverno/v1beta1/updaterequest_types.go b/api/kyverno/v1beta1/updaterequest_types.go index 0252cae11bc1..829667b4bd42 100644 --- a/api/kyverno/v1beta1/updaterequest_types.go +++ b/api/kyverno/v1beta1/updaterequest_types.go @@ -117,7 +117,7 @@ type RequestInfo struct { // AdmissionRequestInfoObject stores the admission request and operation details type AdmissionRequestInfoObject struct { // +optional - AdmissionRequest string `json:"admissionRequest,omitempty" yaml:"admissionRequest,omitempty"` + AdmissionRequest *admissionv1.AdmissionRequest `json:"admissionRequest,omitempty" yaml:"admissionRequest,omitempty"` // +optional Operation admissionv1.Operation `json:"operation,omitempty" yaml:"operation,omitempty"` } diff --git a/api/kyverno/v1beta1/zz_generated.deepcopy.go b/api/kyverno/v1beta1/zz_generated.deepcopy.go index 834327a26793..b388639dd6d5 100644 --- a/api/kyverno/v1beta1/zz_generated.deepcopy.go +++ b/api/kyverno/v1beta1/zz_generated.deepcopy.go @@ -21,12 +21,18 @@ package v1beta1 import ( "github.com/kyverno/kyverno/api/kyverno/v1" + admissionv1 "k8s.io/api/admission/v1" "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AdmissionRequestInfoObject) DeepCopyInto(out *AdmissionRequestInfoObject) { *out = *in + if in.AdmissionRequest != nil { + in, out := &in.AdmissionRequest, &out.AdmissionRequest + *out = new(admissionv1.AdmissionRequest) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmissionRequestInfoObject. @@ -145,7 +151,7 @@ func (in *UpdateRequestSpec) DeepCopy() *UpdateRequestSpec { func (in *UpdateRequestSpecContext) DeepCopyInto(out *UpdateRequestSpecContext) { *out = *in in.UserRequestInfo.DeepCopyInto(&out.UserRequestInfo) - out.AdmissionRequestInfo = in.AdmissionRequestInfo + in.AdmissionRequestInfo.DeepCopyInto(&out.AdmissionRequestInfo) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdateRequestSpecContext. diff --git a/charts/kyverno/templates/crds.yaml b/charts/kyverno/templates/crds.yaml index 1b0f5e1794be..c54d992598ce 100644 --- a/charts/kyverno/templates/crds.yaml +++ b/charts/kyverno/templates/crds.yaml @@ -4577,7 +4577,124 @@ spec: description: AdmissionRequestInfoObject stores the admission request and operation details properties: admissionRequest: - type: string + description: AdmissionRequest describes the admission.Attributes for the admission request. + properties: + dryRun: + description: DryRun indicates that modifications will definitely not be persisted for this request. Defaults to false. + type: boolean + kind: + description: Kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale) + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + name: + description: Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and rely on the server to generate the name. If that is the case, this field will contain an empty string. + type: string + namespace: + description: Namespace is the namespace associated with the request (if any). + type: string + object: + description: Object is the object from the incoming request. + type: object + oldObject: + description: OldObject is the existing object. Only populated for DELETE and UPDATE requests. + type: object + operation: + description: Operation is the operation being performed. This may be different than the operation requested. e.g. a patch can result in either a CREATE or UPDATE Operation. + type: string + options: + description: Options is the operation option structure of the operation being performed. e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be different than the options the caller provided. e.g. for a patch request the performed Operation might be a CREATE, in which case the Options will a `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`. + type: object + requestKind: + description: "RequestKind is the fully-qualified type of the original API request (for example, v1.Pod or autoscaling.v1.Scale). If this is specified and differs from the value in \"kind\", an equivalent match and conversion was performed. \n For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]` and `matchPolicy: Equivalent`, an API request to apps/v1beta1 deployments would be converted and sent to the webhook with `kind: {group:\"apps\", version:\"v1\", kind:\"Deployment\"}` (matching the rule the webhook registered for), and `requestKind: {group:\"apps\", version:\"v1beta1\", kind:\"Deployment\"}` (indicating the kind of the original API request). \n See documentation for the \"matchPolicy\" field in the webhook configuration type for more details." + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + requestResource: + description: "RequestResource is the fully-qualified resource of the original API request (for example, v1.pods). If this is specified and differs from the value in \"resource\", an equivalent match and conversion was performed. \n For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]` and `matchPolicy: Equivalent`, an API request to apps/v1beta1 deployments would be converted and sent to the webhook with `resource: {group:\"apps\", version:\"v1\", resource:\"deployments\"}` (matching the resource the webhook registered for), and `requestResource: {group:\"apps\", version:\"v1beta1\", resource:\"deployments\"}` (indicating the resource of the original API request). \n See documentation for the \"matchPolicy\" field in the webhook configuration type." + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + requestSubResource: + description: RequestSubResource is the name of the subresource of the original API request, if any (for example, "status" or "scale") If this is specified and differs from the value in "subResource", an equivalent match and conversion was performed. See documentation for the "matchPolicy" field in the webhook configuration type. + type: string + resource: + description: Resource is the fully-qualified resource being requested (for example, v1.pods) + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + subResource: + description: SubResource is the subresource being requested, if any (for example, "status" or "scale") + type: string + uid: + description: UID is an identifier for the individual request/response. It allows us to distinguish instances of requests which are otherwise identical (parallel requests, requests when earlier requests did not modify etc) The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request. It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. + type: string + userInfo: + description: UserInfo is information about the requesting user + properties: + extra: + additionalProperties: + description: ExtraValue masks the value so protobuf can generate + items: + type: string + type: array + description: Any additional information provided by the authenticator. + type: object + groups: + description: The names of groups this user is a part of. + items: + type: string + type: array + uid: + description: A unique value that identifies this user across time. If this user is deleted and another user by the same name is added, they will have different UIDs. + type: string + username: + description: The name that uniquely identifies this user among all active users. + type: string + type: object + required: + - kind + - operation + - resource + - uid + - userInfo + type: object operation: description: Operation is the type of resource operation being checked for admission control type: string diff --git a/cmd/initContainer/main.go b/cmd/initContainer/main.go index 6a1c847cad09..2f7f5981b263 100644 --- a/cmd/initContainer/main.go +++ b/cmd/initContainer/main.go @@ -5,6 +5,7 @@ package main import ( "context" + "encoding/json" "flag" "os" "sync" @@ -20,6 +21,7 @@ import ( "github.com/kyverno/kyverno/pkg/signal" "github.com/kyverno/kyverno/pkg/tls" "github.com/kyverno/kyverno/pkg/utils" + admissionv1 "k8s.io/api/admission/v1" coordinationv1 "k8s.io/api/coordination/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -445,42 +447,51 @@ func convertGR(pclient kyvernoclient.Interface) error { } for _, gr := range grs.Items { cp := gr.DeepCopy() - ur := &kyvernov1beta1.UpdateRequest{ - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "ur-", - Namespace: config.KyvernoNamespace(), - Labels: cp.GetLabels(), - }, - Spec: kyvernov1beta1.UpdateRequestSpec{ - Type: kyvernov1beta1.Generate, - Policy: cp.Spec.Policy, - Resource: cp.Spec.Resource, - Context: kyvernov1beta1.UpdateRequestSpecContext{ - UserRequestInfo: kyvernov1beta1.RequestInfo{ - Roles: cp.Spec.Context.UserRequestInfo.Roles, - ClusterRoles: cp.Spec.Context.UserRequestInfo.ClusterRoles, - AdmissionUserInfo: cp.Spec.Context.UserRequestInfo.AdmissionUserInfo, - }, - AdmissionRequestInfo: kyvernov1beta1.AdmissionRequestInfoObject{ - AdmissionRequest: cp.Spec.Context.AdmissionRequestInfo.AdmissionRequest, - Operation: cp.Spec.Context.AdmissionRequestInfo.Operation, + var request *admissionv1.AdmissionRequest + if cp.Spec.Context.AdmissionRequestInfo.AdmissionRequest != "" { + var r admissionv1.AdmissionRequest + if err := json.Unmarshal([]byte(cp.Spec.Context.AdmissionRequestInfo.AdmissionRequest), &r); err == nil { + request = &r + } + } + if err == nil { + ur := &kyvernov1beta1.UpdateRequest{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "ur-", + Namespace: config.KyvernoNamespace(), + Labels: cp.GetLabels(), + }, + Spec: kyvernov1beta1.UpdateRequestSpec{ + Type: kyvernov1beta1.Generate, + Policy: cp.Spec.Policy, + Resource: cp.Spec.Resource, + Context: kyvernov1beta1.UpdateRequestSpecContext{ + UserRequestInfo: kyvernov1beta1.RequestInfo{ + Roles: cp.Spec.Context.UserRequestInfo.Roles, + ClusterRoles: cp.Spec.Context.UserRequestInfo.ClusterRoles, + AdmissionUserInfo: cp.Spec.Context.UserRequestInfo.AdmissionUserInfo, + }, + AdmissionRequestInfo: kyvernov1beta1.AdmissionRequestInfoObject{ + AdmissionRequest: request, + Operation: cp.Spec.Context.AdmissionRequestInfo.Operation, + }, }, }, - }, - } + } - _, err := pclient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(context.TODO(), ur, metav1.CreateOptions{}) - if err != nil { - logger.Info("failed to create UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName(), "err", err.Error()) - errors = append(errors, err) - continue - } else { - logger.Info("successfully created UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName()) - } + _, err := pclient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(context.TODO(), ur, metav1.CreateOptions{}) + if err != nil { + logger.Info("failed to create UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName(), "err", err.Error()) + errors = append(errors, err) + continue + } else { + logger.Info("successfully created UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName()) + } - if err := pclient.KyvernoV1().GenerateRequests(config.KyvernoNamespace()).Delete(context.TODO(), gr.GetName(), metav1.DeleteOptions{}); err != nil { - errors = append(errors, err) - logger.Error(err, "failed to delete GR") + if err := pclient.KyvernoV1().GenerateRequests(config.KyvernoNamespace()).Delete(context.TODO(), gr.GetName(), metav1.DeleteOptions{}); err != nil { + errors = append(errors, err) + logger.Error(err, "failed to delete GR") + } } } diff --git a/config/crds/kyverno.io_updaterequests.yaml b/config/crds/kyverno.io_updaterequests.yaml index cdb6156f848b..4c4b7abb54d1 100644 --- a/config/crds/kyverno.io_updaterequests.yaml +++ b/config/crds/kyverno.io_updaterequests.yaml @@ -68,7 +68,194 @@ spec: and operation details properties: admissionRequest: - type: string + description: AdmissionRequest describes the admission.Attributes + for the admission request. + properties: + dryRun: + description: DryRun indicates that modifications will + definitely not be persisted for this request. Defaults + to false. + type: boolean + kind: + description: Kind is the fully-qualified type of object + being submitted (for example, v1.Pod or autoscaling.v1.Scale) + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + name: + description: Name is the name of the object as presented + in the request. On a CREATE operation, the client may + omit name and rely on the server to generate the name. If + that is the case, this field will contain an empty string. + type: string + namespace: + description: Namespace is the namespace associated with + the request (if any). + type: string + object: + description: Object is the object from the incoming request. + type: object + oldObject: + description: OldObject is the existing object. Only populated + for DELETE and UPDATE requests. + type: object + operation: + description: Operation is the operation being performed. + This may be different than the operation requested. + e.g. a patch can result in either a CREATE or UPDATE + Operation. + type: string + options: + description: Options is the operation option structure + of the operation being performed. e.g. `meta.k8s.io/v1.DeleteOptions` + or `meta.k8s.io/v1.CreateOptions`. This may be different + than the options the caller provided. e.g. for a patch + request the performed Operation might be a CREATE, in + which case the Options will a `meta.k8s.io/v1.CreateOptions` + even though the caller provided `meta.k8s.io/v1.PatchOptions`. + type: object + requestKind: + description: "RequestKind is the fully-qualified type + of the original API request (for example, v1.Pod or + autoscaling.v1.Scale). If this is specified and differs + from the value in \"kind\", an equivalent match and + conversion was performed. \n For example, if deployments + can be modified via apps/v1 and apps/v1beta1, and a + webhook registered a rule of `apiGroups:[\"apps\"], + apiVersions:[\"v1\"], resources: [\"deployments\"]` + and `matchPolicy: Equivalent`, an API request to apps/v1beta1 + deployments would be converted and sent to the webhook + with `kind: {group:\"apps\", version:\"v1\", kind:\"Deployment\"}` + (matching the rule the webhook registered for), and + `requestKind: {group:\"apps\", version:\"v1beta1\", + kind:\"Deployment\"}` (indicating the kind of the original + API request). \n See documentation for the \"matchPolicy\" + field in the webhook configuration type for more details." + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + requestResource: + description: "RequestResource is the fully-qualified resource + of the original API request (for example, v1.pods). + If this is specified and differs from the value in \"resource\", + an equivalent match and conversion was performed. \n + For example, if deployments can be modified via apps/v1 + and apps/v1beta1, and a webhook registered a rule of + `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: + [\"deployments\"]` and `matchPolicy: Equivalent`, an + API request to apps/v1beta1 deployments would be converted + and sent to the webhook with `resource: {group:\"apps\", + version:\"v1\", resource:\"deployments\"}` (matching + the resource the webhook registered for), and `requestResource: + {group:\"apps\", version:\"v1beta1\", resource:\"deployments\"}` + (indicating the resource of the original API request). + \n See documentation for the \"matchPolicy\" field in + the webhook configuration type." + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + requestSubResource: + description: RequestSubResource is the name of the subresource + of the original API request, if any (for example, "status" + or "scale") If this is specified and differs from the + value in "subResource", an equivalent match and conversion + was performed. See documentation for the "matchPolicy" + field in the webhook configuration type. + type: string + resource: + description: Resource is the fully-qualified resource + being requested (for example, v1.pods) + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + subResource: + description: SubResource is the subresource being requested, + if any (for example, "status" or "scale") + type: string + uid: + description: UID is an identifier for the individual request/response. + It allows us to distinguish instances of requests which + are otherwise identical (parallel requests, requests + when earlier requests did not modify etc) The UID is + meant to track the round trip (request/response) between + the KAS and the WebHook, not the user request. It is + suitable for correlating log entries between the webhook + and apiserver, for either auditing or debugging. + type: string + userInfo: + description: UserInfo is information about the requesting + user + properties: + extra: + additionalProperties: + description: ExtraValue masks the value so protobuf + can generate + items: + type: string + type: array + description: Any additional information provided by + the authenticator. + type: object + groups: + description: The names of groups this user is a part + of. + items: + type: string + type: array + uid: + description: A unique value that identifies this user + across time. If this user is deleted and another + user by the same name is added, they will have different + UIDs. + type: string + username: + description: The name that uniquely identifies this + user among all active users. + type: string + type: object + required: + - kind + - operation + - resource + - uid + - userInfo + type: object operation: description: Operation is the type of resource operation being checked for admission control diff --git a/config/install.yaml b/config/install.yaml index 23fc55b94c73..3eb4deadd16f 100644 --- a/config/install.yaml +++ b/config/install.yaml @@ -6904,7 +6904,194 @@ spec: and operation details properties: admissionRequest: - type: string + description: AdmissionRequest describes the admission.Attributes + for the admission request. + properties: + dryRun: + description: DryRun indicates that modifications will + definitely not be persisted for this request. Defaults + to false. + type: boolean + kind: + description: Kind is the fully-qualified type of object + being submitted (for example, v1.Pod or autoscaling.v1.Scale) + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + name: + description: Name is the name of the object as presented + in the request. On a CREATE operation, the client may + omit name and rely on the server to generate the name. If + that is the case, this field will contain an empty string. + type: string + namespace: + description: Namespace is the namespace associated with + the request (if any). + type: string + object: + description: Object is the object from the incoming request. + type: object + oldObject: + description: OldObject is the existing object. Only populated + for DELETE and UPDATE requests. + type: object + operation: + description: Operation is the operation being performed. + This may be different than the operation requested. + e.g. a patch can result in either a CREATE or UPDATE + Operation. + type: string + options: + description: Options is the operation option structure + of the operation being performed. e.g. `meta.k8s.io/v1.DeleteOptions` + or `meta.k8s.io/v1.CreateOptions`. This may be different + than the options the caller provided. e.g. for a patch + request the performed Operation might be a CREATE, in + which case the Options will a `meta.k8s.io/v1.CreateOptions` + even though the caller provided `meta.k8s.io/v1.PatchOptions`. + type: object + requestKind: + description: "RequestKind is the fully-qualified type + of the original API request (for example, v1.Pod or + autoscaling.v1.Scale). If this is specified and differs + from the value in \"kind\", an equivalent match and + conversion was performed. \n For example, if deployments + can be modified via apps/v1 and apps/v1beta1, and a + webhook registered a rule of `apiGroups:[\"apps\"], + apiVersions:[\"v1\"], resources: [\"deployments\"]` + and `matchPolicy: Equivalent`, an API request to apps/v1beta1 + deployments would be converted and sent to the webhook + with `kind: {group:\"apps\", version:\"v1\", kind:\"Deployment\"}` + (matching the rule the webhook registered for), and + `requestKind: {group:\"apps\", version:\"v1beta1\", + kind:\"Deployment\"}` (indicating the kind of the original + API request). \n See documentation for the \"matchPolicy\" + field in the webhook configuration type for more details." + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + requestResource: + description: "RequestResource is the fully-qualified resource + of the original API request (for example, v1.pods). + If this is specified and differs from the value in \"resource\", + an equivalent match and conversion was performed. \n + For example, if deployments can be modified via apps/v1 + and apps/v1beta1, and a webhook registered a rule of + `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: + [\"deployments\"]` and `matchPolicy: Equivalent`, an + API request to apps/v1beta1 deployments would be converted + and sent to the webhook with `resource: {group:\"apps\", + version:\"v1\", resource:\"deployments\"}` (matching + the resource the webhook registered for), and `requestResource: + {group:\"apps\", version:\"v1beta1\", resource:\"deployments\"}` + (indicating the resource of the original API request). + \n See documentation for the \"matchPolicy\" field in + the webhook configuration type." + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + requestSubResource: + description: RequestSubResource is the name of the subresource + of the original API request, if any (for example, "status" + or "scale") If this is specified and differs from the + value in "subResource", an equivalent match and conversion + was performed. See documentation for the "matchPolicy" + field in the webhook configuration type. + type: string + resource: + description: Resource is the fully-qualified resource + being requested (for example, v1.pods) + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + subResource: + description: SubResource is the subresource being requested, + if any (for example, "status" or "scale") + type: string + uid: + description: UID is an identifier for the individual request/response. + It allows us to distinguish instances of requests which + are otherwise identical (parallel requests, requests + when earlier requests did not modify etc) The UID is + meant to track the round trip (request/response) between + the KAS and the WebHook, not the user request. It is + suitable for correlating log entries between the webhook + and apiserver, for either auditing or debugging. + type: string + userInfo: + description: UserInfo is information about the requesting + user + properties: + extra: + additionalProperties: + description: ExtraValue masks the value so protobuf + can generate + items: + type: string + type: array + description: Any additional information provided by + the authenticator. + type: object + groups: + description: The names of groups this user is a part + of. + items: + type: string + type: array + uid: + description: A unique value that identifies this user + across time. If this user is deleted and another + user by the same name is added, they will have different + UIDs. + type: string + username: + description: The name that uniquely identifies this + user among all active users. + type: string + type: object + required: + - kind + - operation + - resource + - uid + - userInfo + type: object operation: description: Operation is the type of resource operation being checked for admission control diff --git a/config/install_debug.yaml b/config/install_debug.yaml index 3ce071292bc2..f5204cd9ca34 100755 --- a/config/install_debug.yaml +++ b/config/install_debug.yaml @@ -6895,7 +6895,194 @@ spec: and operation details properties: admissionRequest: - type: string + description: AdmissionRequest describes the admission.Attributes + for the admission request. + properties: + dryRun: + description: DryRun indicates that modifications will + definitely not be persisted for this request. Defaults + to false. + type: boolean + kind: + description: Kind is the fully-qualified type of object + being submitted (for example, v1.Pod or autoscaling.v1.Scale) + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + name: + description: Name is the name of the object as presented + in the request. On a CREATE operation, the client may + omit name and rely on the server to generate the name. If + that is the case, this field will contain an empty string. + type: string + namespace: + description: Namespace is the namespace associated with + the request (if any). + type: string + object: + description: Object is the object from the incoming request. + type: object + oldObject: + description: OldObject is the existing object. Only populated + for DELETE and UPDATE requests. + type: object + operation: + description: Operation is the operation being performed. + This may be different than the operation requested. + e.g. a patch can result in either a CREATE or UPDATE + Operation. + type: string + options: + description: Options is the operation option structure + of the operation being performed. e.g. `meta.k8s.io/v1.DeleteOptions` + or `meta.k8s.io/v1.CreateOptions`. This may be different + than the options the caller provided. e.g. for a patch + request the performed Operation might be a CREATE, in + which case the Options will a `meta.k8s.io/v1.CreateOptions` + even though the caller provided `meta.k8s.io/v1.PatchOptions`. + type: object + requestKind: + description: "RequestKind is the fully-qualified type + of the original API request (for example, v1.Pod or + autoscaling.v1.Scale). If this is specified and differs + from the value in \"kind\", an equivalent match and + conversion was performed. \n For example, if deployments + can be modified via apps/v1 and apps/v1beta1, and a + webhook registered a rule of `apiGroups:[\"apps\"], + apiVersions:[\"v1\"], resources: [\"deployments\"]` + and `matchPolicy: Equivalent`, an API request to apps/v1beta1 + deployments would be converted and sent to the webhook + with `kind: {group:\"apps\", version:\"v1\", kind:\"Deployment\"}` + (matching the rule the webhook registered for), and + `requestKind: {group:\"apps\", version:\"v1beta1\", + kind:\"Deployment\"}` (indicating the kind of the original + API request). \n See documentation for the \"matchPolicy\" + field in the webhook configuration type for more details." + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + requestResource: + description: "RequestResource is the fully-qualified resource + of the original API request (for example, v1.pods). + If this is specified and differs from the value in \"resource\", + an equivalent match and conversion was performed. \n + For example, if deployments can be modified via apps/v1 + and apps/v1beta1, and a webhook registered a rule of + `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: + [\"deployments\"]` and `matchPolicy: Equivalent`, an + API request to apps/v1beta1 deployments would be converted + and sent to the webhook with `resource: {group:\"apps\", + version:\"v1\", resource:\"deployments\"}` (matching + the resource the webhook registered for), and `requestResource: + {group:\"apps\", version:\"v1beta1\", resource:\"deployments\"}` + (indicating the resource of the original API request). + \n See documentation for the \"matchPolicy\" field in + the webhook configuration type." + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + requestSubResource: + description: RequestSubResource is the name of the subresource + of the original API request, if any (for example, "status" + or "scale") If this is specified and differs from the + value in "subResource", an equivalent match and conversion + was performed. See documentation for the "matchPolicy" + field in the webhook configuration type. + type: string + resource: + description: Resource is the fully-qualified resource + being requested (for example, v1.pods) + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + subResource: + description: SubResource is the subresource being requested, + if any (for example, "status" or "scale") + type: string + uid: + description: UID is an identifier for the individual request/response. + It allows us to distinguish instances of requests which + are otherwise identical (parallel requests, requests + when earlier requests did not modify etc) The UID is + meant to track the round trip (request/response) between + the KAS and the WebHook, not the user request. It is + suitable for correlating log entries between the webhook + and apiserver, for either auditing or debugging. + type: string + userInfo: + description: UserInfo is information about the requesting + user + properties: + extra: + additionalProperties: + description: ExtraValue masks the value so protobuf + can generate + items: + type: string + type: array + description: Any additional information provided by + the authenticator. + type: object + groups: + description: The names of groups this user is a part + of. + items: + type: string + type: array + uid: + description: A unique value that identifies this user + across time. If this user is deleted and another + user by the same name is added, they will have different + UIDs. + type: string + username: + description: The name that uniquely identifies this + user among all active users. + type: string + type: object + required: + - kind + - operation + - resource + - uid + - userInfo + type: object operation: description: Operation is the type of resource operation being checked for admission control diff --git a/docs/crd/v1beta1/index.html b/docs/crd/v1beta1/index.html index 17acd873315b..98eb3dfaff2c 100644 --- a/docs/crd/v1beta1/index.html +++ b/docs/crd/v1beta1/index.html @@ -178,7 +178,9 @@

AdmissionRequestInfoObjec admissionRequest
-string + +Kubernetes admission/v1.AdmissionRequest + diff --git a/pkg/background/common/context.go b/pkg/background/common/context.go index 5a2a2bb1ca22..81e5bdb2eb1d 100644 --- a/pkg/background/common/context.go +++ b/pkg/background/common/context.go @@ -1,7 +1,6 @@ package common import ( - "encoding/json" "fmt" "reflect" @@ -14,7 +13,6 @@ import ( "github.com/kyverno/kyverno/pkg/engine/context" utils "github.com/kyverno/kyverno/pkg/utils" "github.com/pkg/errors" - admissionv1 "k8s.io/api/admission/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -26,21 +24,15 @@ func NewBackgroundContext(dclient dclient.Interface, ur *kyvernov1beta1.UpdateRe logger logr.Logger, ) (*engine.PolicyContext, bool, error) { ctx := context.NewContext() - requestString := ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest - var request admissionv1.AdmissionRequest var new, old unstructured.Unstructured + var err error - if requestString != "" { - err := json.Unmarshal([]byte(requestString), &request) - if err != nil { - return nil, false, errors.Wrap(err, "error parsing the request string") - } - - if err := ctx.AddRequest(&request); err != nil { + if ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest != nil { + if err := ctx.AddRequest(ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest); err != nil { return nil, false, errors.Wrap(err, "failed to load request in context") } - new, old, err = utils.ExtractResources(nil, &request) + new, old, err = utils.ExtractResources(nil, ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest) if err != nil { return nil, false, errors.Wrap(err, "failed to load request in context") } @@ -61,7 +53,7 @@ func NewBackgroundContext(dclient dclient.Interface, ur *kyvernov1beta1.UpdateRe return nil, false, errors.New("trigger resource does not exist") } - err := ctx.AddResource(trigger.Object) + err = ctx.AddResource(trigger.Object) if err != nil { return nil, false, errors.Wrap(err, "failed to load resource in context") } diff --git a/pkg/webhooks/resource/utils.go b/pkg/webhooks/resource/utils.go index 8b73e536cc90..6dca7ffb6fac 100644 --- a/pkg/webhooks/resource/utils.go +++ b/pkg/webhooks/resource/utils.go @@ -5,7 +5,6 @@ import ( "fmt" "strings" - "github.com/gardener/controller-manager-library/pkg/logger" "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" @@ -318,12 +317,8 @@ func stripNonPolicyFields(obj, newRes map[string]interface{}, logger logr.Logger func applyUpdateRequest(request *admissionv1.AdmissionRequest, ruleType kyvernov1beta1.RequestType, grGenerator updaterequest.Generator, userRequestInfo kyvernov1beta1.RequestInfo, action admissionv1.Operation, engineResponses ...*response.EngineResponse, ) (failedUpdateRequest []updateRequestResponse) { - requestBytes, err := json.Marshal(request) - if err != nil { - logger.Error(err, "error loading request into context") - } admissionRequestInfo := kyvernov1beta1.AdmissionRequestInfoObject{ - AdmissionRequest: string(requestBytes), + AdmissionRequest: request, Operation: action, } From 2f79cb61c2bddfa24bd36525434e86d7fb080c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Wed, 25 May 2022 14:25:16 +0200 Subject: [PATCH 3/4] refactor: used typed admission request in ur MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Charles-Edouard Brétéché --- Makefile | 3 +- api/kyverno/v1beta1/updaterequest_types.go | 2 +- api/kyverno/v1beta1/zz_generated.deepcopy.go | 8 +- charts/kyverno/templates/crds.yaml | 170 +++++++++---- cmd/initContainer/main.go | 75 +++--- config/crds/kyverno.io_clusterpolicies.yaml | 6 - ...yverno.io_clusterreportchangerequests.yaml | 6 - config/crds/kyverno.io_generaterequests.yaml | 6 - config/crds/kyverno.io_policies.yaml | 6 - .../crds/kyverno.io_reportchangerequests.yaml | 6 - config/crds/kyverno.io_updaterequests.yaml | 198 ++++++++++++++- .../wgpolicyk8s.io_clusterpolicyreports.yaml | 6 - config/crds/wgpolicyk8s.io_policyreports.yaml | 6 - config/install.yaml | 240 ++++++++++++++---- config/install_debug.yaml | 240 ++++++++++++++---- docs/crd/v1/index.html | 4 +- docs/crd/v1beta1/index.html | 4 +- pkg/background/common/context.go | 18 +- pkg/background/update_request_controller.go | 3 + pkg/webhooks/resource/utils.go | 7 +- pkg/webhooks/updaterequest/generator.go | 1 + 21 files changed, 762 insertions(+), 253 deletions(-) diff --git a/Makefile b/Makefile index 86244cb94097..8b3b4e5067f1 100644 --- a/Makefile +++ b/Makefile @@ -372,7 +372,8 @@ install-controller-gen: ## Install controller-gen CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\ cd $$CONTROLLER_GEN_TMP_DIR ;\ go mod init tmp ;\ - go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_REQ_VERSION) ;\ + go mod edit -replace=sigs.k8s.io/controller-tools@$(CONTROLLER_GEN_REQ_VERSION)=github.com/eddycharly/controller-tools@704af868d45a3a78448b9a6a2279c12ea96a621e ;\ + go get sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_GEN_REQ_VERSION) ;\ rm -rf $$CONTROLLER_GEN_TMP_DIR ;\ } CONTROLLER_GEN=$(GOPATH)/bin/controller-gen diff --git a/api/kyverno/v1beta1/updaterequest_types.go b/api/kyverno/v1beta1/updaterequest_types.go index 0252cae11bc1..829667b4bd42 100644 --- a/api/kyverno/v1beta1/updaterequest_types.go +++ b/api/kyverno/v1beta1/updaterequest_types.go @@ -117,7 +117,7 @@ type RequestInfo struct { // AdmissionRequestInfoObject stores the admission request and operation details type AdmissionRequestInfoObject struct { // +optional - AdmissionRequest string `json:"admissionRequest,omitempty" yaml:"admissionRequest,omitempty"` + AdmissionRequest *admissionv1.AdmissionRequest `json:"admissionRequest,omitempty" yaml:"admissionRequest,omitempty"` // +optional Operation admissionv1.Operation `json:"operation,omitempty" yaml:"operation,omitempty"` } diff --git a/api/kyverno/v1beta1/zz_generated.deepcopy.go b/api/kyverno/v1beta1/zz_generated.deepcopy.go index 834327a26793..b388639dd6d5 100644 --- a/api/kyverno/v1beta1/zz_generated.deepcopy.go +++ b/api/kyverno/v1beta1/zz_generated.deepcopy.go @@ -21,12 +21,18 @@ package v1beta1 import ( "github.com/kyverno/kyverno/api/kyverno/v1" + admissionv1 "k8s.io/api/admission/v1" "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AdmissionRequestInfoObject) DeepCopyInto(out *AdmissionRequestInfoObject) { *out = *in + if in.AdmissionRequest != nil { + in, out := &in.AdmissionRequest, &out.AdmissionRequest + *out = new(admissionv1.AdmissionRequest) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdmissionRequestInfoObject. @@ -145,7 +151,7 @@ func (in *UpdateRequestSpec) DeepCopy() *UpdateRequestSpec { func (in *UpdateRequestSpecContext) DeepCopyInto(out *UpdateRequestSpecContext) { *out = *in in.UserRequestInfo.DeepCopyInto(&out.UserRequestInfo) - out.AdmissionRequestInfo = in.AdmissionRequestInfo + in.AdmissionRequestInfo.DeepCopyInto(&out.AdmissionRequestInfo) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpdateRequestSpecContext. diff --git a/charts/kyverno/templates/crds.yaml b/charts/kyverno/templates/crds.yaml index 1b0f5e1794be..bf1283b43bbb 100644 --- a/charts/kyverno/templates/crds.yaml +++ b/charts/kyverno/templates/crds.yaml @@ -1611,12 +1611,6 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -1883,12 +1877,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2155,12 +2143,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2336,12 +2318,6 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -3955,12 +3931,6 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -4227,12 +4197,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -4499,12 +4463,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -4577,7 +4535,127 @@ spec: description: AdmissionRequestInfoObject stores the admission request and operation details properties: admissionRequest: - type: string + description: AdmissionRequest describes the admission.Attributes for the admission request. + properties: + dryRun: + description: DryRun indicates that modifications will definitely not be persisted for this request. Defaults to false. + type: boolean + kind: + description: Kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale) + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + name: + description: Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and rely on the server to generate the name. If that is the case, this field will contain an empty string. + type: string + namespace: + description: Namespace is the namespace associated with the request (if any). + type: string + object: + description: Object is the object from the incoming request. + type: object + x-kubernetes-preserve-unknown-fields: true + oldObject: + description: OldObject is the existing object. Only populated for DELETE and UPDATE requests. + type: object + x-kubernetes-preserve-unknown-fields: true + operation: + description: Operation is the operation being performed. This may be different than the operation requested. e.g. a patch can result in either a CREATE or UPDATE Operation. + type: string + options: + description: Options is the operation option structure of the operation being performed. e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be different than the options the caller provided. e.g. for a patch request the performed Operation might be a CREATE, in which case the Options will a `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`. + type: object + x-kubernetes-preserve-unknown-fields: true + requestKind: + description: "RequestKind is the fully-qualified type of the original API request (for example, v1.Pod or autoscaling.v1.Scale). If this is specified and differs from the value in \"kind\", an equivalent match and conversion was performed. \n For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]` and `matchPolicy: Equivalent`, an API request to apps/v1beta1 deployments would be converted and sent to the webhook with `kind: {group:\"apps\", version:\"v1\", kind:\"Deployment\"}` (matching the rule the webhook registered for), and `requestKind: {group:\"apps\", version:\"v1beta1\", kind:\"Deployment\"}` (indicating the kind of the original API request). \n See documentation for the \"matchPolicy\" field in the webhook configuration type for more details." + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + requestResource: + description: "RequestResource is the fully-qualified resource of the original API request (for example, v1.pods). If this is specified and differs from the value in \"resource\", an equivalent match and conversion was performed. \n For example, if deployments can be modified via apps/v1 and apps/v1beta1, and a webhook registered a rule of `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: [\"deployments\"]` and `matchPolicy: Equivalent`, an API request to apps/v1beta1 deployments would be converted and sent to the webhook with `resource: {group:\"apps\", version:\"v1\", resource:\"deployments\"}` (matching the resource the webhook registered for), and `requestResource: {group:\"apps\", version:\"v1beta1\", resource:\"deployments\"}` (indicating the resource of the original API request). \n See documentation for the \"matchPolicy\" field in the webhook configuration type." + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + requestSubResource: + description: RequestSubResource is the name of the subresource of the original API request, if any (for example, "status" or "scale") If this is specified and differs from the value in "subResource", an equivalent match and conversion was performed. See documentation for the "matchPolicy" field in the webhook configuration type. + type: string + resource: + description: Resource is the fully-qualified resource being requested (for example, v1.pods) + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + subResource: + description: SubResource is the subresource being requested, if any (for example, "status" or "scale") + type: string + uid: + description: UID is an identifier for the individual request/response. It allows us to distinguish instances of requests which are otherwise identical (parallel requests, requests when earlier requests did not modify etc) The UID is meant to track the round trip (request/response) between the KAS and the WebHook, not the user request. It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. + type: string + userInfo: + description: UserInfo is information about the requesting user + properties: + extra: + additionalProperties: + description: ExtraValue masks the value so protobuf can generate + items: + type: string + type: array + description: Any additional information provided by the authenticator. + type: object + groups: + description: The names of groups this user is a part of. + items: + type: string + type: array + uid: + description: A unique value that identifies this user across time. If this user is deleted and another user by the same name is added, they will have different UIDs. + type: string + username: + description: The name that uniquely identifies this user among all active users. + type: string + type: object + required: + - kind + - operation + - resource + - uid + - userInfo + type: object operation: description: Operation is the type of resource operation being checked for admission control type: string @@ -4690,10 +4768,4 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] {{- end }} diff --git a/cmd/initContainer/main.go b/cmd/initContainer/main.go index 6a1c847cad09..2f7f5981b263 100644 --- a/cmd/initContainer/main.go +++ b/cmd/initContainer/main.go @@ -5,6 +5,7 @@ package main import ( "context" + "encoding/json" "flag" "os" "sync" @@ -20,6 +21,7 @@ import ( "github.com/kyverno/kyverno/pkg/signal" "github.com/kyverno/kyverno/pkg/tls" "github.com/kyverno/kyverno/pkg/utils" + admissionv1 "k8s.io/api/admission/v1" coordinationv1 "k8s.io/api/coordination/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -445,42 +447,51 @@ func convertGR(pclient kyvernoclient.Interface) error { } for _, gr := range grs.Items { cp := gr.DeepCopy() - ur := &kyvernov1beta1.UpdateRequest{ - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "ur-", - Namespace: config.KyvernoNamespace(), - Labels: cp.GetLabels(), - }, - Spec: kyvernov1beta1.UpdateRequestSpec{ - Type: kyvernov1beta1.Generate, - Policy: cp.Spec.Policy, - Resource: cp.Spec.Resource, - Context: kyvernov1beta1.UpdateRequestSpecContext{ - UserRequestInfo: kyvernov1beta1.RequestInfo{ - Roles: cp.Spec.Context.UserRequestInfo.Roles, - ClusterRoles: cp.Spec.Context.UserRequestInfo.ClusterRoles, - AdmissionUserInfo: cp.Spec.Context.UserRequestInfo.AdmissionUserInfo, - }, - AdmissionRequestInfo: kyvernov1beta1.AdmissionRequestInfoObject{ - AdmissionRequest: cp.Spec.Context.AdmissionRequestInfo.AdmissionRequest, - Operation: cp.Spec.Context.AdmissionRequestInfo.Operation, + var request *admissionv1.AdmissionRequest + if cp.Spec.Context.AdmissionRequestInfo.AdmissionRequest != "" { + var r admissionv1.AdmissionRequest + if err := json.Unmarshal([]byte(cp.Spec.Context.AdmissionRequestInfo.AdmissionRequest), &r); err == nil { + request = &r + } + } + if err == nil { + ur := &kyvernov1beta1.UpdateRequest{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "ur-", + Namespace: config.KyvernoNamespace(), + Labels: cp.GetLabels(), + }, + Spec: kyvernov1beta1.UpdateRequestSpec{ + Type: kyvernov1beta1.Generate, + Policy: cp.Spec.Policy, + Resource: cp.Spec.Resource, + Context: kyvernov1beta1.UpdateRequestSpecContext{ + UserRequestInfo: kyvernov1beta1.RequestInfo{ + Roles: cp.Spec.Context.UserRequestInfo.Roles, + ClusterRoles: cp.Spec.Context.UserRequestInfo.ClusterRoles, + AdmissionUserInfo: cp.Spec.Context.UserRequestInfo.AdmissionUserInfo, + }, + AdmissionRequestInfo: kyvernov1beta1.AdmissionRequestInfoObject{ + AdmissionRequest: request, + Operation: cp.Spec.Context.AdmissionRequestInfo.Operation, + }, }, }, - }, - } + } - _, err := pclient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(context.TODO(), ur, metav1.CreateOptions{}) - if err != nil { - logger.Info("failed to create UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName(), "err", err.Error()) - errors = append(errors, err) - continue - } else { - logger.Info("successfully created UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName()) - } + _, err := pclient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(context.TODO(), ur, metav1.CreateOptions{}) + if err != nil { + logger.Info("failed to create UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName(), "err", err.Error()) + errors = append(errors, err) + continue + } else { + logger.Info("successfully created UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName()) + } - if err := pclient.KyvernoV1().GenerateRequests(config.KyvernoNamespace()).Delete(context.TODO(), gr.GetName(), metav1.DeleteOptions{}); err != nil { - errors = append(errors, err) - logger.Error(err, "failed to delete GR") + if err := pclient.KyvernoV1().GenerateRequests(config.KyvernoNamespace()).Delete(context.TODO(), gr.GetName(), metav1.DeleteOptions{}); err != nil { + errors = append(errors, err) + logger.Error(err, "failed to delete GR") + } } } diff --git a/config/crds/kyverno.io_clusterpolicies.yaml b/config/crds/kyverno.io_clusterpolicies.yaml index 55f65375480a..7e0ff540ea76 100644 --- a/config/crds/kyverno.io_clusterpolicies.yaml +++ b/config/crds/kyverno.io_clusterpolicies.yaml @@ -2561,9 +2561,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/kyverno.io_clusterreportchangerequests.yaml b/config/crds/kyverno.io_clusterreportchangerequests.yaml index 0cd5fd4294e0..f04db480d065 100644 --- a/config/crds/kyverno.io_clusterreportchangerequests.yaml +++ b/config/crds/kyverno.io_clusterreportchangerequests.yaml @@ -354,9 +354,3 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/kyverno.io_generaterequests.yaml b/config/crds/kyverno.io_generaterequests.yaml index c09eb7ae6d75..b8ce629f2bec 100644 --- a/config/crds/kyverno.io_generaterequests.yaml +++ b/config/crds/kyverno.io_generaterequests.yaml @@ -182,9 +182,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/kyverno.io_policies.yaml b/config/crds/kyverno.io_policies.yaml index e667f837fb30..617aa19a1db3 100644 --- a/config/crds/kyverno.io_policies.yaml +++ b/config/crds/kyverno.io_policies.yaml @@ -2563,9 +2563,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/kyverno.io_reportchangerequests.yaml b/config/crds/kyverno.io_reportchangerequests.yaml index 5777287df0e4..5d4b014271fc 100644 --- a/config/crds/kyverno.io_reportchangerequests.yaml +++ b/config/crds/kyverno.io_reportchangerequests.yaml @@ -354,9 +354,3 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/kyverno.io_updaterequests.yaml b/config/crds/kyverno.io_updaterequests.yaml index cdb6156f848b..212154e3b677 100644 --- a/config/crds/kyverno.io_updaterequests.yaml +++ b/config/crds/kyverno.io_updaterequests.yaml @@ -68,7 +68,197 @@ spec: and operation details properties: admissionRequest: - type: string + description: AdmissionRequest describes the admission.Attributes + for the admission request. + properties: + dryRun: + description: DryRun indicates that modifications will + definitely not be persisted for this request. Defaults + to false. + type: boolean + kind: + description: Kind is the fully-qualified type of object + being submitted (for example, v1.Pod or autoscaling.v1.Scale) + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + name: + description: Name is the name of the object as presented + in the request. On a CREATE operation, the client may + omit name and rely on the server to generate the name. If + that is the case, this field will contain an empty string. + type: string + namespace: + description: Namespace is the namespace associated with + the request (if any). + type: string + object: + description: Object is the object from the incoming request. + type: object + x-kubernetes-preserve-unknown-fields: true + oldObject: + description: OldObject is the existing object. Only populated + for DELETE and UPDATE requests. + type: object + x-kubernetes-preserve-unknown-fields: true + operation: + description: Operation is the operation being performed. + This may be different than the operation requested. + e.g. a patch can result in either a CREATE or UPDATE + Operation. + type: string + options: + description: Options is the operation option structure + of the operation being performed. e.g. `meta.k8s.io/v1.DeleteOptions` + or `meta.k8s.io/v1.CreateOptions`. This may be different + than the options the caller provided. e.g. for a patch + request the performed Operation might be a CREATE, in + which case the Options will a `meta.k8s.io/v1.CreateOptions` + even though the caller provided `meta.k8s.io/v1.PatchOptions`. + type: object + x-kubernetes-preserve-unknown-fields: true + requestKind: + description: "RequestKind is the fully-qualified type + of the original API request (for example, v1.Pod or + autoscaling.v1.Scale). If this is specified and differs + from the value in \"kind\", an equivalent match and + conversion was performed. \n For example, if deployments + can be modified via apps/v1 and apps/v1beta1, and a + webhook registered a rule of `apiGroups:[\"apps\"], + apiVersions:[\"v1\"], resources: [\"deployments\"]` + and `matchPolicy: Equivalent`, an API request to apps/v1beta1 + deployments would be converted and sent to the webhook + with `kind: {group:\"apps\", version:\"v1\", kind:\"Deployment\"}` + (matching the rule the webhook registered for), and + `requestKind: {group:\"apps\", version:\"v1beta1\", + kind:\"Deployment\"}` (indicating the kind of the original + API request). \n See documentation for the \"matchPolicy\" + field in the webhook configuration type for more details." + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + requestResource: + description: "RequestResource is the fully-qualified resource + of the original API request (for example, v1.pods). + If this is specified and differs from the value in \"resource\", + an equivalent match and conversion was performed. \n + For example, if deployments can be modified via apps/v1 + and apps/v1beta1, and a webhook registered a rule of + `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: + [\"deployments\"]` and `matchPolicy: Equivalent`, an + API request to apps/v1beta1 deployments would be converted + and sent to the webhook with `resource: {group:\"apps\", + version:\"v1\", resource:\"deployments\"}` (matching + the resource the webhook registered for), and `requestResource: + {group:\"apps\", version:\"v1beta1\", resource:\"deployments\"}` + (indicating the resource of the original API request). + \n See documentation for the \"matchPolicy\" field in + the webhook configuration type." + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + requestSubResource: + description: RequestSubResource is the name of the subresource + of the original API request, if any (for example, "status" + or "scale") If this is specified and differs from the + value in "subResource", an equivalent match and conversion + was performed. See documentation for the "matchPolicy" + field in the webhook configuration type. + type: string + resource: + description: Resource is the fully-qualified resource + being requested (for example, v1.pods) + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + subResource: + description: SubResource is the subresource being requested, + if any (for example, "status" or "scale") + type: string + uid: + description: UID is an identifier for the individual request/response. + It allows us to distinguish instances of requests which + are otherwise identical (parallel requests, requests + when earlier requests did not modify etc) The UID is + meant to track the round trip (request/response) between + the KAS and the WebHook, not the user request. It is + suitable for correlating log entries between the webhook + and apiserver, for either auditing or debugging. + type: string + userInfo: + description: UserInfo is information about the requesting + user + properties: + extra: + additionalProperties: + description: ExtraValue masks the value so protobuf + can generate + items: + type: string + type: array + description: Any additional information provided by + the authenticator. + type: object + groups: + description: The names of groups this user is a part + of. + items: + type: string + type: array + uid: + description: A unique value that identifies this user + across time. If this user is deleted and another + user by the same name is added, they will have different + UIDs. + type: string + username: + description: The name that uniquely identifies this + user among all active users. + type: string + type: object + required: + - kind + - operation + - resource + - uid + - userInfo + type: object operation: description: Operation is the type of resource operation being checked for admission control @@ -193,9 +383,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/wgpolicyk8s.io_clusterpolicyreports.yaml b/config/crds/wgpolicyk8s.io_clusterpolicyreports.yaml index 4bb6b6000637..990c4e9f2334 100644 --- a/config/crds/wgpolicyk8s.io_clusterpolicyreports.yaml +++ b/config/crds/wgpolicyk8s.io_clusterpolicyreports.yaml @@ -354,9 +354,3 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crds/wgpolicyk8s.io_policyreports.yaml b/config/crds/wgpolicyk8s.io_policyreports.yaml index 099c5610a569..e5b1c792ae28 100644 --- a/config/crds/wgpolicyk8s.io_policyreports.yaml +++ b/config/crds/wgpolicyk8s.io_policyreports.yaml @@ -353,9 +353,3 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/install.yaml b/config/install.yaml index 23fc55b94c73..e8e45733ccbd 100644 --- a/config/install.yaml +++ b/config/install.yaml @@ -2578,12 +2578,6 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2946,12 +2940,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -3314,12 +3302,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -3510,12 +3492,6 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6087,12 +6063,6 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6454,12 +6424,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6822,12 +6786,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6904,7 +6862,197 @@ spec: and operation details properties: admissionRequest: - type: string + description: AdmissionRequest describes the admission.Attributes + for the admission request. + properties: + dryRun: + description: DryRun indicates that modifications will + definitely not be persisted for this request. Defaults + to false. + type: boolean + kind: + description: Kind is the fully-qualified type of object + being submitted (for example, v1.Pod or autoscaling.v1.Scale) + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + name: + description: Name is the name of the object as presented + in the request. On a CREATE operation, the client may + omit name and rely on the server to generate the name. If + that is the case, this field will contain an empty string. + type: string + namespace: + description: Namespace is the namespace associated with + the request (if any). + type: string + object: + description: Object is the object from the incoming request. + type: object + x-kubernetes-preserve-unknown-fields: true + oldObject: + description: OldObject is the existing object. Only populated + for DELETE and UPDATE requests. + type: object + x-kubernetes-preserve-unknown-fields: true + operation: + description: Operation is the operation being performed. + This may be different than the operation requested. + e.g. a patch can result in either a CREATE or UPDATE + Operation. + type: string + options: + description: Options is the operation option structure + of the operation being performed. e.g. `meta.k8s.io/v1.DeleteOptions` + or `meta.k8s.io/v1.CreateOptions`. This may be different + than the options the caller provided. e.g. for a patch + request the performed Operation might be a CREATE, in + which case the Options will a `meta.k8s.io/v1.CreateOptions` + even though the caller provided `meta.k8s.io/v1.PatchOptions`. + type: object + x-kubernetes-preserve-unknown-fields: true + requestKind: + description: "RequestKind is the fully-qualified type + of the original API request (for example, v1.Pod or + autoscaling.v1.Scale). If this is specified and differs + from the value in \"kind\", an equivalent match and + conversion was performed. \n For example, if deployments + can be modified via apps/v1 and apps/v1beta1, and a + webhook registered a rule of `apiGroups:[\"apps\"], + apiVersions:[\"v1\"], resources: [\"deployments\"]` + and `matchPolicy: Equivalent`, an API request to apps/v1beta1 + deployments would be converted and sent to the webhook + with `kind: {group:\"apps\", version:\"v1\", kind:\"Deployment\"}` + (matching the rule the webhook registered for), and + `requestKind: {group:\"apps\", version:\"v1beta1\", + kind:\"Deployment\"}` (indicating the kind of the original + API request). \n See documentation for the \"matchPolicy\" + field in the webhook configuration type for more details." + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + requestResource: + description: "RequestResource is the fully-qualified resource + of the original API request (for example, v1.pods). + If this is specified and differs from the value in \"resource\", + an equivalent match and conversion was performed. \n + For example, if deployments can be modified via apps/v1 + and apps/v1beta1, and a webhook registered a rule of + `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: + [\"deployments\"]` and `matchPolicy: Equivalent`, an + API request to apps/v1beta1 deployments would be converted + and sent to the webhook with `resource: {group:\"apps\", + version:\"v1\", resource:\"deployments\"}` (matching + the resource the webhook registered for), and `requestResource: + {group:\"apps\", version:\"v1beta1\", resource:\"deployments\"}` + (indicating the resource of the original API request). + \n See documentation for the \"matchPolicy\" field in + the webhook configuration type." + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + requestSubResource: + description: RequestSubResource is the name of the subresource + of the original API request, if any (for example, "status" + or "scale") If this is specified and differs from the + value in "subResource", an equivalent match and conversion + was performed. See documentation for the "matchPolicy" + field in the webhook configuration type. + type: string + resource: + description: Resource is the fully-qualified resource + being requested (for example, v1.pods) + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + subResource: + description: SubResource is the subresource being requested, + if any (for example, "status" or "scale") + type: string + uid: + description: UID is an identifier for the individual request/response. + It allows us to distinguish instances of requests which + are otherwise identical (parallel requests, requests + when earlier requests did not modify etc) The UID is + meant to track the round trip (request/response) between + the KAS and the WebHook, not the user request. It is + suitable for correlating log entries between the webhook + and apiserver, for either auditing or debugging. + type: string + userInfo: + description: UserInfo is information about the requesting + user + properties: + extra: + additionalProperties: + description: ExtraValue masks the value so protobuf + can generate + items: + type: string + type: array + description: Any additional information provided by + the authenticator. + type: object + groups: + description: The names of groups this user is a part + of. + items: + type: string + type: array + uid: + description: A unique value that identifies this user + across time. If this user is deleted and another + user by the same name is added, they will have different + UIDs. + type: string + username: + description: The name that uniquely identifies this + user among all active users. + type: string + type: object + required: + - kind + - operation + - resource + - uid + - userInfo + type: object operation: description: Operation is the type of resource operation being checked for admission control @@ -7029,12 +7177,6 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: v1 kind: ServiceAccount diff --git a/config/install_debug.yaml b/config/install_debug.yaml index 3ce071292bc2..eb252329a899 100755 --- a/config/install_debug.yaml +++ b/config/install_debug.yaml @@ -2576,12 +2576,6 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -2943,12 +2937,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -3310,12 +3298,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -3505,12 +3487,6 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6081,12 +6057,6 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6447,12 +6417,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6814,12 +6778,6 @@ spec: served: true storage: true subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6895,7 +6853,197 @@ spec: and operation details properties: admissionRequest: - type: string + description: AdmissionRequest describes the admission.Attributes + for the admission request. + properties: + dryRun: + description: DryRun indicates that modifications will + definitely not be persisted for this request. Defaults + to false. + type: boolean + kind: + description: Kind is the fully-qualified type of object + being submitted (for example, v1.Pod or autoscaling.v1.Scale) + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + name: + description: Name is the name of the object as presented + in the request. On a CREATE operation, the client may + omit name and rely on the server to generate the name. If + that is the case, this field will contain an empty string. + type: string + namespace: + description: Namespace is the namespace associated with + the request (if any). + type: string + object: + description: Object is the object from the incoming request. + type: object + x-kubernetes-preserve-unknown-fields: true + oldObject: + description: OldObject is the existing object. Only populated + for DELETE and UPDATE requests. + type: object + x-kubernetes-preserve-unknown-fields: true + operation: + description: Operation is the operation being performed. + This may be different than the operation requested. + e.g. a patch can result in either a CREATE or UPDATE + Operation. + type: string + options: + description: Options is the operation option structure + of the operation being performed. e.g. `meta.k8s.io/v1.DeleteOptions` + or `meta.k8s.io/v1.CreateOptions`. This may be different + than the options the caller provided. e.g. for a patch + request the performed Operation might be a CREATE, in + which case the Options will a `meta.k8s.io/v1.CreateOptions` + even though the caller provided `meta.k8s.io/v1.PatchOptions`. + type: object + x-kubernetes-preserve-unknown-fields: true + requestKind: + description: "RequestKind is the fully-qualified type + of the original API request (for example, v1.Pod or + autoscaling.v1.Scale). If this is specified and differs + from the value in \"kind\", an equivalent match and + conversion was performed. \n For example, if deployments + can be modified via apps/v1 and apps/v1beta1, and a + webhook registered a rule of `apiGroups:[\"apps\"], + apiVersions:[\"v1\"], resources: [\"deployments\"]` + and `matchPolicy: Equivalent`, an API request to apps/v1beta1 + deployments would be converted and sent to the webhook + with `kind: {group:\"apps\", version:\"v1\", kind:\"Deployment\"}` + (matching the rule the webhook registered for), and + `requestKind: {group:\"apps\", version:\"v1beta1\", + kind:\"Deployment\"}` (indicating the kind of the original + API request). \n See documentation for the \"matchPolicy\" + field in the webhook configuration type for more details." + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + requestResource: + description: "RequestResource is the fully-qualified resource + of the original API request (for example, v1.pods). + If this is specified and differs from the value in \"resource\", + an equivalent match and conversion was performed. \n + For example, if deployments can be modified via apps/v1 + and apps/v1beta1, and a webhook registered a rule of + `apiGroups:[\"apps\"], apiVersions:[\"v1\"], resources: + [\"deployments\"]` and `matchPolicy: Equivalent`, an + API request to apps/v1beta1 deployments would be converted + and sent to the webhook with `resource: {group:\"apps\", + version:\"v1\", resource:\"deployments\"}` (matching + the resource the webhook registered for), and `requestResource: + {group:\"apps\", version:\"v1beta1\", resource:\"deployments\"}` + (indicating the resource of the original API request). + \n See documentation for the \"matchPolicy\" field in + the webhook configuration type." + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + requestSubResource: + description: RequestSubResource is the name of the subresource + of the original API request, if any (for example, "status" + or "scale") If this is specified and differs from the + value in "subResource", an equivalent match and conversion + was performed. See documentation for the "matchPolicy" + field in the webhook configuration type. + type: string + resource: + description: Resource is the fully-qualified resource + being requested (for example, v1.pods) + properties: + group: + type: string + resource: + type: string + version: + type: string + required: + - group + - resource + - version + type: object + subResource: + description: SubResource is the subresource being requested, + if any (for example, "status" or "scale") + type: string + uid: + description: UID is an identifier for the individual request/response. + It allows us to distinguish instances of requests which + are otherwise identical (parallel requests, requests + when earlier requests did not modify etc) The UID is + meant to track the round trip (request/response) between + the KAS and the WebHook, not the user request. It is + suitable for correlating log entries between the webhook + and apiserver, for either auditing or debugging. + type: string + userInfo: + description: UserInfo is information about the requesting + user + properties: + extra: + additionalProperties: + description: ExtraValue masks the value so protobuf + can generate + items: + type: string + type: array + description: Any additional information provided by + the authenticator. + type: object + groups: + description: The names of groups this user is a part + of. + items: + type: string + type: array + uid: + description: A unique value that identifies this user + across time. If this user is deleted and another + user by the same name is added, they will have different + UIDs. + type: string + username: + description: The name that uniquely identifies this + user among all active users. + type: string + type: object + required: + - kind + - operation + - resource + - uid + - userInfo + type: object operation: description: Operation is the type of resource operation being checked for admission control @@ -7020,12 +7168,6 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] --- apiVersion: v1 kind: ServiceAccount diff --git a/docs/crd/v1/index.html b/docs/crd/v1/index.html index 51fcf08c648c..44f250d0a941 100644 --- a/docs/crd/v1/index.html +++ b/docs/crd/v1/index.html @@ -1837,7 +1837,7 @@

ImageExtractorConfig

ImageExtractorConfigs -(map[string][]./api/kyverno/v1.ImageExtractorConfig alias)

+(map[string][]github.com/kyverno/kyverno/api/kyverno/v1.ImageExtractorConfig alias)

(Appears on: Rule) @@ -2605,7 +2605,7 @@

ResourceFilter

ResourceFilters -([]./api/kyverno/v1.ResourceFilter alias)

+([]github.com/kyverno/kyverno/api/kyverno/v1.ResourceFilter alias)

(Appears on: MatchResources) diff --git a/docs/crd/v1beta1/index.html b/docs/crd/v1beta1/index.html index 17acd873315b..98eb3dfaff2c 100644 --- a/docs/crd/v1beta1/index.html +++ b/docs/crd/v1beta1/index.html @@ -178,7 +178,9 @@

AdmissionRequestInfoObjec admissionRequest
-string + +Kubernetes admission/v1.AdmissionRequest + diff --git a/pkg/background/common/context.go b/pkg/background/common/context.go index 5a2a2bb1ca22..81e5bdb2eb1d 100644 --- a/pkg/background/common/context.go +++ b/pkg/background/common/context.go @@ -1,7 +1,6 @@ package common import ( - "encoding/json" "fmt" "reflect" @@ -14,7 +13,6 @@ import ( "github.com/kyverno/kyverno/pkg/engine/context" utils "github.com/kyverno/kyverno/pkg/utils" "github.com/pkg/errors" - admissionv1 "k8s.io/api/admission/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -26,21 +24,15 @@ func NewBackgroundContext(dclient dclient.Interface, ur *kyvernov1beta1.UpdateRe logger logr.Logger, ) (*engine.PolicyContext, bool, error) { ctx := context.NewContext() - requestString := ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest - var request admissionv1.AdmissionRequest var new, old unstructured.Unstructured + var err error - if requestString != "" { - err := json.Unmarshal([]byte(requestString), &request) - if err != nil { - return nil, false, errors.Wrap(err, "error parsing the request string") - } - - if err := ctx.AddRequest(&request); err != nil { + if ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest != nil { + if err := ctx.AddRequest(ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest); err != nil { return nil, false, errors.Wrap(err, "failed to load request in context") } - new, old, err = utils.ExtractResources(nil, &request) + new, old, err = utils.ExtractResources(nil, ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest) if err != nil { return nil, false, errors.Wrap(err, "failed to load request in context") } @@ -61,7 +53,7 @@ func NewBackgroundContext(dclient dclient.Interface, ur *kyvernov1beta1.UpdateRe return nil, false, errors.New("trigger resource does not exist") } - err := ctx.AddResource(trigger.Object) + err = ctx.AddResource(trigger.Object) if err != nil { return nil, false, errors.Wrap(err, "failed to load resource in context") } diff --git a/pkg/background/update_request_controller.go b/pkg/background/update_request_controller.go index d1a924587d84..bddf9c3c1c44 100644 --- a/pkg/background/update_request_controller.go +++ b/pkg/background/update_request_controller.go @@ -171,6 +171,9 @@ func (c *controller) syncUpdateRequest(key string) error { if err != nil { return err } + if ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest != nil { + logger.Info("get ur", "object", string(ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest.Object.Raw)) + } // if not in any state, try to set it to pending if ur.Status.State == "" { ur = ur.DeepCopy() diff --git a/pkg/webhooks/resource/utils.go b/pkg/webhooks/resource/utils.go index 8b73e536cc90..6dca7ffb6fac 100644 --- a/pkg/webhooks/resource/utils.go +++ b/pkg/webhooks/resource/utils.go @@ -5,7 +5,6 @@ import ( "fmt" "strings" - "github.com/gardener/controller-manager-library/pkg/logger" "github.com/go-logr/logr" kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1" kyvernov1beta1 "github.com/kyverno/kyverno/api/kyverno/v1beta1" @@ -318,12 +317,8 @@ func stripNonPolicyFields(obj, newRes map[string]interface{}, logger logr.Logger func applyUpdateRequest(request *admissionv1.AdmissionRequest, ruleType kyvernov1beta1.RequestType, grGenerator updaterequest.Generator, userRequestInfo kyvernov1beta1.RequestInfo, action admissionv1.Operation, engineResponses ...*response.EngineResponse, ) (failedUpdateRequest []updateRequestResponse) { - requestBytes, err := json.Marshal(request) - if err != nil { - logger.Error(err, "error loading request into context") - } admissionRequestInfo := kyvernov1beta1.AdmissionRequestInfoObject{ - AdmissionRequest: string(requestBytes), + AdmissionRequest: request, Operation: action, } diff --git a/pkg/webhooks/updaterequest/generator.go b/pkg/webhooks/updaterequest/generator.go index f186245ccea5..df1082aadb5d 100644 --- a/pkg/webhooks/updaterequest/generator.go +++ b/pkg/webhooks/updaterequest/generator.go @@ -107,6 +107,7 @@ func (g *generator) tryApplyResource(policyName string, urSpec kyvernov1beta1.Up }, Spec: urSpec, } + l.Info("create ur", "object", string(ur.Spec.Context.AdmissionRequestInfo.AdmissionRequest.Object.Raw)) if new, err := g.client.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(context.TODO(), &ur, metav1.CreateOptions{}); err != nil { l.V(4).Error(err, "failed to create UpdateRequest, retrying", "name", ur.GetGenerateName(), "namespace", ur.GetNamespace()) return err From c1cd96fbba75c4036305c191709572f7c68f7eaa Mon Sep 17 00:00:00 2001 From: ShutingZhao Date: Sun, 29 May 2022 15:08:03 +0800 Subject: [PATCH 4/4] Handle the error properly Signed-off-by: ShutingZhao --- cmd/initContainer/main.go | 73 ++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/cmd/initContainer/main.go b/cmd/initContainer/main.go index 2f7f5981b263..ecb1ec50607d 100644 --- a/cmd/initContainer/main.go +++ b/cmd/initContainer/main.go @@ -450,48 +450,49 @@ func convertGR(pclient kyvernoclient.Interface) error { var request *admissionv1.AdmissionRequest if cp.Spec.Context.AdmissionRequestInfo.AdmissionRequest != "" { var r admissionv1.AdmissionRequest - if err := json.Unmarshal([]byte(cp.Spec.Context.AdmissionRequestInfo.AdmissionRequest), &r); err == nil { - request = &r + err := json.Unmarshal([]byte(cp.Spec.Context.AdmissionRequestInfo.AdmissionRequest), &r) + if err != nil { + logger.Error(err, "failed to unmarshal admission request") + errors = append(errors, err) + continue } } - if err == nil { - ur := &kyvernov1beta1.UpdateRequest{ - ObjectMeta: metav1.ObjectMeta{ - GenerateName: "ur-", - Namespace: config.KyvernoNamespace(), - Labels: cp.GetLabels(), - }, - Spec: kyvernov1beta1.UpdateRequestSpec{ - Type: kyvernov1beta1.Generate, - Policy: cp.Spec.Policy, - Resource: cp.Spec.Resource, - Context: kyvernov1beta1.UpdateRequestSpecContext{ - UserRequestInfo: kyvernov1beta1.RequestInfo{ - Roles: cp.Spec.Context.UserRequestInfo.Roles, - ClusterRoles: cp.Spec.Context.UserRequestInfo.ClusterRoles, - AdmissionUserInfo: cp.Spec.Context.UserRequestInfo.AdmissionUserInfo, - }, - AdmissionRequestInfo: kyvernov1beta1.AdmissionRequestInfoObject{ - AdmissionRequest: request, - Operation: cp.Spec.Context.AdmissionRequestInfo.Operation, - }, + ur := &kyvernov1beta1.UpdateRequest{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "ur-", + Namespace: config.KyvernoNamespace(), + Labels: cp.GetLabels(), + }, + Spec: kyvernov1beta1.UpdateRequestSpec{ + Type: kyvernov1beta1.Generate, + Policy: cp.Spec.Policy, + Resource: cp.Spec.Resource, + Context: kyvernov1beta1.UpdateRequestSpecContext{ + UserRequestInfo: kyvernov1beta1.RequestInfo{ + Roles: cp.Spec.Context.UserRequestInfo.Roles, + ClusterRoles: cp.Spec.Context.UserRequestInfo.ClusterRoles, + AdmissionUserInfo: cp.Spec.Context.UserRequestInfo.AdmissionUserInfo, + }, + AdmissionRequestInfo: kyvernov1beta1.AdmissionRequestInfoObject{ + AdmissionRequest: request, + Operation: cp.Spec.Context.AdmissionRequestInfo.Operation, }, }, - } + }, + } - _, err := pclient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(context.TODO(), ur, metav1.CreateOptions{}) - if err != nil { - logger.Info("failed to create UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName(), "err", err.Error()) - errors = append(errors, err) - continue - } else { - logger.Info("successfully created UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName()) - } + _, err := pclient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).Create(context.TODO(), ur, metav1.CreateOptions{}) + if err != nil { + logger.Info("failed to create UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName(), "err", err.Error()) + errors = append(errors, err) + continue + } else { + logger.Info("successfully created UpdateRequest", "GR namespace", gr.GetNamespace(), "GR name", gr.GetName()) + } - if err := pclient.KyvernoV1().GenerateRequests(config.KyvernoNamespace()).Delete(context.TODO(), gr.GetName(), metav1.DeleteOptions{}); err != nil { - errors = append(errors, err) - logger.Error(err, "failed to delete GR") - } + if err := pclient.KyvernoV1().GenerateRequests(config.KyvernoNamespace()).Delete(context.TODO(), gr.GetName(), metav1.DeleteOptions{}); err != nil { + errors = append(errors, err) + logger.Error(err, "failed to delete GR") } }