diff --git a/deploy/webhook/clusterrole.yaml b/deploy/webhook/clusterrole.yaml index 06e1f03cb..a21c72fac 100644 --- a/deploy/webhook/clusterrole.yaml +++ b/deploy/webhook/clusterrole.yaml @@ -11,3 +11,6 @@ rules: - apiGroups: ["authorization.k8s.io"] resources: ["subjectaccessreviews"] verbs: ["create"] +- apiGroups: ["flowcontrol.apiserver.k8s.io"] + resources: ["prioritylevelconfigurations", "flowschemas"] + verbs: ["get", "list", "watch"] diff --git a/deploy/webhook/webhook.yaml b/deploy/webhook/webhook.yaml index c2e9a8286..91db4184e 100644 --- a/deploy/webhook/webhook.yaml +++ b/deploy/webhook/webhook.yaml @@ -21,7 +21,7 @@ webhooks: - "*" resources: - managedclusters - admissionReviewVersions: ["v1beta1"] + admissionReviewVersions: ["v1"] sideEffects: None timeoutSeconds: 3 @@ -50,7 +50,7 @@ webhooks: - "*" resources: - managedclusters - admissionReviewVersions: ["v1beta1"] + admissionReviewVersions: ["v1"] sideEffects: None timeoutSeconds: 3 @@ -79,6 +79,6 @@ webhooks: - "*" resources: - managedclustersetbindings - admissionReviewVersions: ["v1beta1"] + admissionReviewVersions: ["v1"] sideEffects: None timeoutSeconds: 3 diff --git a/go.mod b/go.mod index 727d721c2..dd13a9e61 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/open-cluster-management/api v0.0.0-20210409125704-06f2aec1a73f github.com/openshift/api v0.0.0-20210331193751-3acddb19d360 github.com/openshift/build-machinery-go v0.0.0-20210209125900-0da259a2c359 - github.com/openshift/generic-admission-server v1.14.1-0.20200903115324-4ddcdd976480 + github.com/openshift/generic-admission-server v1.14.1-0.20210422140326-da96454c926d github.com/openshift/library-go v0.0.0-20210407140145-f831e911c638 github.com/spf13/cobra v1.1.1 github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index ab555b22a..e47f27807 100644 --- a/go.sum +++ b/go.sum @@ -436,8 +436,8 @@ github.com/openshift/build-machinery-go v0.0.0-20210115170933-e575b44a7a94/go.mo github.com/openshift/build-machinery-go v0.0.0-20210209125900-0da259a2c359 h1:ehSDsWQiUVzJZrSEXMC7ceV9JIPEyTYqrpqu3m4Wa08= github.com/openshift/build-machinery-go v0.0.0-20210209125900-0da259a2c359/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/openshift/client-go v0.0.0-20210331195552-cf6c2669e01f/go.mod h1:hHaRJ6vp2MRd/CpuZ1oJkqnMGy5eEnoAkQmKPZKcUPI= -github.com/openshift/generic-admission-server v1.14.1-0.20200903115324-4ddcdd976480 h1:y47BAJFepK8Xls1c+quIOyc46OXiT9LRiqGVjIaMlSA= -github.com/openshift/generic-admission-server v1.14.1-0.20200903115324-4ddcdd976480/go.mod h1:OAHL5WnZphlhVEf5fTdeGLvNwMu1B2zCWpmxJpCA35o= +github.com/openshift/generic-admission-server v1.14.1-0.20210422140326-da96454c926d h1:Z5xcujYaukvRqLWxBiIRn6KdM5Pd1De01fmfD1Rr4dk= +github.com/openshift/generic-admission-server v1.14.1-0.20210422140326-da96454c926d/go.mod h1:m+wYlVQdnPe8JGqoKVpCYnFRIVraqC1SrUowQXh6XlA= github.com/openshift/library-go v0.0.0-20210407140145-f831e911c638 h1:JVMywK3dwzPAwpTCWIHn2Emx5L11I+0OR15CZXHI4do= github.com/openshift/library-go v0.0.0-20210407140145-f831e911c638/go.mod h1:pnz961veImKsbn7pQcuFbcVpCQosYiC1fUOjzEDeOLU= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -919,6 +919,7 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= k8s.io/api v0.18.0-beta.2/go.mod h1:2oeNnWEqcSmaM/ibSh3t7xcIqbkGXhzZdn4ezV9T4m0= k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw= +k8s.io/api v0.19.5/go.mod h1:yGZReuNa0vj56op6eT+NLrXJne0R0u9ktexZ8jdJzpc= k8s.io/api v0.20.0 h1:WwrYoZNM1W1aQEbyl8HNG+oWGzLpZQBlcerS9BQw9yI= k8s.io/api v0.20.0/go.mod h1:HyLC5l5eoS/ygQYl1BXBgFzWNlkHiAuyNAbevIn+FKg= k8s.io/api v0.21.0-rc.0 h1:t/kW96KdNJNamYNqxaxRirahK+FaWJQ6BJPbXm5Jb+o= @@ -932,6 +933,7 @@ k8s.io/apiextensions-apiserver v0.21.0-rc.0/go.mod h1:ItIoMBJU1gy93Qwr/B2699r4b0 k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= k8s.io/apimachinery v0.18.0-beta.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.19.0/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= +k8s.io/apimachinery v0.19.5/go.mod h1:6sRbGRAVY5DOCuZwB5XkqguBqpqLU6q/kOaOdk29z6Q= k8s.io/apimachinery v0.20.0 h1:jjzbTJRXk0unNS71L7h3lxGDH/2HPxMPaQY+MjECKL8= k8s.io/apimachinery v0.20.0/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.21.0-rc.0 h1:m9dyzHb8QZAHOZKIz2SiabSif1oLsfgrnwiago/9xJA= @@ -944,6 +946,7 @@ k8s.io/apiserver v0.21.0-rc.0/go.mod h1:QlW7+1CZTZtAcKvJ34/n4DIb8sC93FeQpkd1KSU+ k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= k8s.io/client-go v0.18.0-beta.2/go.mod h1:UvuVxHjKWIcgy0iMvF+bwNDW7l0mskTNOaOW1Qv5BMA= k8s.io/client-go v0.19.0/go.mod h1:H9E/VT95blcFQnlyShFgnFT9ZnJOAceiUHM3MlRC+mU= +k8s.io/client-go v0.19.5/go.mod h1:BSG3iuxI40Bs0nNDLS1JRa/7ReBQDHzf0x8nZZrK0fo= k8s.io/client-go v0.20.0 h1:Xlax8PKbZsjX4gFvNtt4F5MoJ1V5prDvCuoq9B7iax0= k8s.io/client-go v0.20.0/go.mod h1:4KWh/g+Ocd8KkCwKF8vUNnmqgv+EVnQDK4MBF4oB5tY= k8s.io/client-go v0.21.0-rc.0 h1:lsPZHT1ZniXJcwg2udlaTOhAT8wf7BE0rn9Vj0+LWMA= @@ -956,6 +959,7 @@ k8s.io/code-generator v0.21.0-rc.0/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64 k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc= k8s.io/component-base v0.18.0-beta.2/go.mod h1:HVk5FpRnyzQ/MjBr9//e/yEBjTVa2qjGXCTuUzcD7ks= k8s.io/component-base v0.19.0/go.mod h1:dKsY8BxkA+9dZIAh2aWJLL/UdASFDNtGYTCItL4LM7Y= +k8s.io/component-base v0.19.5/go.mod h1:5N/uv5A7fyr0d+t/b1HynXKkUVPEhc8ljkMaBJv4Tp8= k8s.io/component-base v0.21.0-rc.0 h1:8YgFPDsIhRx7zCOxikZn77nYRnwxrc9aMiuQDJtK1+g= k8s.io/component-base v0.21.0-rc.0/go.mod h1:XlP0bM7QJFWRGZYPc5NmphkvsYQ+o7804HWH3GTGjDY= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= diff --git a/pkg/webhook/cluster/mutating_webhook.go b/pkg/webhook/cluster/mutating_webhook.go index 5146a7b55..c78bc1312 100644 --- a/pkg/webhook/cluster/mutating_webhook.go +++ b/pkg/webhook/cluster/mutating_webhook.go @@ -6,7 +6,7 @@ import ( clusterv1 "github.com/open-cluster-management/api/cluster/v1" - admissionv1beta1 "k8s.io/api/admission/v1beta1" + admissionv1 "k8s.io/api/admission/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/rest" @@ -30,10 +30,10 @@ func (a *ManagedClusterMutatingAdmissionHook) MutatingResource() (schema.GroupVe } // Admit is called by generic-admission-server when the registered REST resource above is called with an admission request. -func (a *ManagedClusterMutatingAdmissionHook) Admit(req *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse { +func (a *ManagedClusterMutatingAdmissionHook) Admit(req *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse { klog.V(4).Infof("mutate %q operation for object %q", req.Operation, req.Object) - status := &admissionv1beta1.AdmissionResponse{ + status := &admissionv1.AdmissionResponse{ Allowed: true, } @@ -44,7 +44,7 @@ func (a *ManagedClusterMutatingAdmissionHook) Admit(req *admissionv1beta1.Admiss } // only mutate create and update operation - if req.Operation != admissionv1beta1.Create && req.Operation != admissionv1beta1.Update { + if req.Operation != admissionv1.Create && req.Operation != admissionv1.Update { return status } @@ -61,7 +61,7 @@ func (a *ManagedClusterMutatingAdmissionHook) Admit(req *admissionv1beta1.Admiss // If LeaseDurationSeconds value is zero, update it to 60 by default if managedCluster.Spec.LeaseDurationSeconds == 0 { status.Patch = []byte(defaultLeaseDurationSecondsPatch) - pt := admissionv1beta1.PatchTypeJSONPatch + pt := admissionv1.PatchTypeJSONPatch status.PatchType = &pt } diff --git a/pkg/webhook/cluster/mutating_webhook_test.go b/pkg/webhook/cluster/mutating_webhook_test.go index 98c61f6c7..fe92e2d47 100644 --- a/pkg/webhook/cluster/mutating_webhook_test.go +++ b/pkg/webhook/cluster/mutating_webhook_test.go @@ -6,50 +6,50 @@ import ( "testing" testinghelpers "github.com/open-cluster-management/registration/pkg/helpers/testing" - admissionv1beta1 "k8s.io/api/admission/v1beta1" + admissionv1 "k8s.io/api/admission/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) func TestManagedClusterMutate(t *testing.T) { - pt := admissionv1beta1.PatchTypeJSONPatch + pt := admissionv1.PatchTypeJSONPatch cases := []struct { name string - request *admissionv1beta1.AdmissionRequest - expectedResponse *admissionv1beta1.AdmissionResponse + request *admissionv1.AdmissionRequest + expectedResponse *admissionv1.AdmissionResponse allowUpdateAcceptField bool }{ { name: "mutate non-managedclusters request", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: metav1.GroupVersionResource{ Group: "test.open-cluster-management.io", Version: "v1", Resource: "tests", }, }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, }, { name: "mutate deleting operation", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Delete, + Operation: admissionv1.Delete, }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, }, { name: "mutate a ManagedCluster without LeaseDurationSeconds setting", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Create, + Operation: admissionv1.Create, Object: newManagedClusterObj(), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, Patch: []byte(`[{"op": "replace", "path": "/spec/leaseDurationSeconds", "value": 60}]`), PatchType: &pt, @@ -57,12 +57,12 @@ func TestManagedClusterMutate(t *testing.T) { }, { name: "mutate a ManagedCluster with LeaseDurationSeconds setting", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Create, + Operation: admissionv1.Create, Object: newManagedClusterObjWithLeaseDurationSeconds(60), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, }, diff --git a/pkg/webhook/cluster/validating_webhook.go b/pkg/webhook/cluster/validating_webhook.go index 936c5d93a..8bd7b1878 100644 --- a/pkg/webhook/cluster/validating_webhook.go +++ b/pkg/webhook/cluster/validating_webhook.go @@ -11,7 +11,7 @@ import ( operatorhelpers "github.com/openshift/library-go/pkg/operator/v1helpers" - admissionv1beta1 "k8s.io/api/admission/v1beta1" + admissionv1 "k8s.io/api/admission/v1" authenticationv1 "k8s.io/api/authentication/v1" authorizationv1 "k8s.io/api/authorization/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -43,10 +43,10 @@ func (a *ManagedClusterValidatingAdmissionHook) ValidatingResource() (plural sch } // Validate is called by generic-admission-server when the registered REST resource above is called with an admission request. -func (a *ManagedClusterValidatingAdmissionHook) Validate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse { +func (a *ManagedClusterValidatingAdmissionHook) Validate(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse { klog.V(4).Infof("validate %q operation for object %q", admissionSpec.Operation, admissionSpec.Object) - status := &admissionv1beta1.AdmissionResponse{} + status := &admissionv1.AdmissionResponse{} // only validate the request for managedcluster if admissionSpec.Resource.Group != "cluster.open-cluster-management.io" || @@ -56,9 +56,9 @@ func (a *ManagedClusterValidatingAdmissionHook) Validate(admissionSpec *admissio } switch admissionSpec.Operation { - case admissionv1beta1.Create: + case admissionv1.Create: return a.validateCreateRequest(admissionSpec) - case admissionv1beta1.Update: + case admissionv1.Update: return a.validateUpdateRequest(admissionSpec) default: status.Allowed = true @@ -74,8 +74,8 @@ func (a *ManagedClusterValidatingAdmissionHook) Initialize(kubeClientConfig *res } // validateCreateRequest validates create managed cluster operation -func (a *ManagedClusterValidatingAdmissionHook) validateCreateRequest(request *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse { - status := &admissionv1beta1.AdmissionResponse{} +func (a *ManagedClusterValidatingAdmissionHook) validateCreateRequest(request *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse { + status := &admissionv1.AdmissionResponse{} // validate ManagedCluster object firstly managedCluster, err := a.validateManagedClusterObj(request.Object) @@ -106,8 +106,8 @@ func (a *ManagedClusterValidatingAdmissionHook) validateCreateRequest(request *a } // validateUpdateRequest validates update managed cluster operation. -func (a *ManagedClusterValidatingAdmissionHook) validateUpdateRequest(request *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse { - status := &admissionv1beta1.AdmissionResponse{} +func (a *ManagedClusterValidatingAdmissionHook) validateUpdateRequest(request *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse { + status := &admissionv1.AdmissionResponse{} oldManagedCluster := &clusterv1.ManagedCluster{} if err := json.Unmarshal(request.OldObject.Raw, oldManagedCluster); err != nil { @@ -176,8 +176,8 @@ func (a *ManagedClusterValidatingAdmissionHook) validateManagedClusterObj(reques // allowUpdateHubAcceptsClientField using SubjectAccessReview API to check whether a request user has been authorized to update // HubAcceptsClient field -func (a *ManagedClusterValidatingAdmissionHook) allowUpdateAcceptField(clusterName string, userInfo authenticationv1.UserInfo) *admissionv1beta1.AdmissionResponse { - status := &admissionv1beta1.AdmissionResponse{} +func (a *ManagedClusterValidatingAdmissionHook) allowUpdateAcceptField(clusterName string, userInfo authenticationv1.UserInfo) *admissionv1.AdmissionResponse { + status := &admissionv1.AdmissionResponse{} extra := make(map[string]authorizationv1.ExtraValue) for k, v := range userInfo.Extra { @@ -223,9 +223,9 @@ func (a *ManagedClusterValidatingAdmissionHook) allowUpdateAcceptField(clusterNa } // allowSetClusterSetLabel checks whether a request user has been authorized to set clusterset label -func (a *ManagedClusterValidatingAdmissionHook) allowSetClusterSetLabel(userInfo authenticationv1.UserInfo, originalClusterSet, newClusterSet string) *admissionv1beta1.AdmissionResponse { +func (a *ManagedClusterValidatingAdmissionHook) allowSetClusterSetLabel(userInfo authenticationv1.UserInfo, originalClusterSet, newClusterSet string) *admissionv1.AdmissionResponse { if originalClusterSet == newClusterSet { - return &admissionv1beta1.AdmissionResponse{Allowed: true} + return &admissionv1.AdmissionResponse{Allowed: true} } if len(originalClusterSet) > 0 { @@ -240,15 +240,15 @@ func (a *ManagedClusterValidatingAdmissionHook) allowSetClusterSetLabel(userInfo } } - return &admissionv1beta1.AdmissionResponse{ + return &admissionv1.AdmissionResponse{ Allowed: true, } } // allowUpdateClusterSet checks whether a request user has been authorized to add/remove a ManagedCluster // to/from the ManagedClusterSet -func (a *ManagedClusterValidatingAdmissionHook) allowUpdateClusterSet(userInfo authenticationv1.UserInfo, clusterSetName string) *admissionv1beta1.AdmissionResponse { - status := &admissionv1beta1.AdmissionResponse{} +func (a *ManagedClusterValidatingAdmissionHook) allowUpdateClusterSet(userInfo authenticationv1.UserInfo, clusterSetName string) *admissionv1.AdmissionResponse { + status := &admissionv1.AdmissionResponse{} extra := make(map[string]authorizationv1.ExtraValue) for k, v := range userInfo.Extra { diff --git a/pkg/webhook/cluster/validating_webhook_test.go b/pkg/webhook/cluster/validating_webhook_test.go index 2aec05128..f4fa77d65 100644 --- a/pkg/webhook/cluster/validating_webhook_test.go +++ b/pkg/webhook/cluster/validating_webhook_test.go @@ -10,7 +10,7 @@ import ( clusterv1alpha1 "github.com/open-cluster-management/api/cluster/v1alpha1" testinghelpers "github.com/open-cluster-management/registration/pkg/helpers/testing" - admissionv1beta1 "k8s.io/api/admission/v1beta1" + admissionv1 "k8s.io/api/admission/v1" authenticationv1 "k8s.io/api/authentication/v1" authorizationv1 "k8s.io/api/authorization/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -28,53 +28,53 @@ var managedclustersSchema = metav1.GroupVersionResource{ func TestManagedClusterValidate(t *testing.T) { cases := []struct { name string - request *admissionv1beta1.AdmissionRequest - expectedResponse *admissionv1beta1.AdmissionResponse + request *admissionv1.AdmissionRequest + expectedResponse *admissionv1.AdmissionResponse allowUpdateAcceptField bool allowUpdateClusterSets map[string]bool }{ { name: "validate non-managedclusters request", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: metav1.GroupVersionResource{ Group: "test.open-cluster-management.io", Version: "v1", Resource: "tests", }, }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, }, { name: "validate deleting operation", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Delete, + Operation: admissionv1.Delete, }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, }, { name: "validate creating ManagedCluster", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Create, + Operation: admissionv1.Create, Object: newManagedClusterObj(), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, }, { name: "validate creating ManagedCluster with invalid fields", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Create, + Operation: admissionv1.Create, Object: newManagedClusterObjWithClientConfigs(clusterv1.ClientConfig{URL: "http://127.0.0.1:8001"}), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: false, Result: &metav1.Status{ Status: metav1.StatusFailure, Code: http.StatusBadRequest, Reason: metav1.StatusReasonBadRequest, @@ -84,13 +84,13 @@ func TestManagedClusterValidate(t *testing.T) { }, { name: "validate creating an accepted ManagedCluster without update acceptance permission", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Create, + Operation: admissionv1.Create, Object: newManagedClusterObjWithHubAcceptsClient(true), UserInfo: authenticationv1.UserInfo{Username: "tester"}, }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: false, Result: &metav1.Status{ Status: metav1.StatusFailure, Code: http.StatusForbidden, Reason: metav1.StatusReasonForbidden, @@ -100,38 +100,38 @@ func TestManagedClusterValidate(t *testing.T) { }, { name: "validate creating an accepted ManagedCluster", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Create, + Operation: admissionv1.Create, Object: newManagedClusterObjWithHubAcceptsClient(true), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, allowUpdateAcceptField: true, }, { name: "validate update ManagedCluster without HubAcceptsClient field changed", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Update, + Operation: admissionv1.Update, OldObject: newManagedClusterObjWithClientConfigs(clusterv1.ClientConfig{URL: "https://127.0.0.1:6443"}), Object: newManagedClusterObjWithClientConfigs(clusterv1.ClientConfig{URL: "https://127.0.0.1:8443"}), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, }, { name: "validate updating HubAcceptsClient field without update acceptance permission", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Update, + Operation: admissionv1.Update, OldObject: newManagedClusterObjWithHubAcceptsClient(false), Object: newManagedClusterObjWithHubAcceptsClient(true), UserInfo: authenticationv1.UserInfo{Username: "tester"}, }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: false, Result: &metav1.Status{ Status: metav1.StatusFailure, Code: http.StatusForbidden, Reason: metav1.StatusReasonForbidden, @@ -141,25 +141,25 @@ func TestManagedClusterValidate(t *testing.T) { }, { name: "validate updating HubAcceptsClient field", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Update, + Operation: admissionv1.Update, OldObject: newManagedClusterObjWithHubAcceptsClient(false), Object: newManagedClusterObjWithHubAcceptsClient(true), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, allowUpdateAcceptField: true, }, { name: "validate setting clusterset label", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Create, + Operation: admissionv1.Create, Object: newManagedClusterObjWithClientSet("clusterset1"), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, allowUpdateClusterSets: map[string]bool{ @@ -168,12 +168,12 @@ func TestManagedClusterValidate(t *testing.T) { }, { name: "validate setting clusterset label without permission", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Create, + Operation: admissionv1.Create, Object: newManagedClusterObjWithClientSet("clusterset1"), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: false, Result: &metav1.Status{ Status: metav1.StatusFailure, Code: http.StatusForbidden, Reason: metav1.StatusReasonForbidden, @@ -186,13 +186,13 @@ func TestManagedClusterValidate(t *testing.T) { }, { name: "validate updating clusterset label", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Update, + Operation: admissionv1.Update, OldObject: newManagedClusterObjWithClientSet("clusterset1"), Object: newManagedClusterObjWithClientSet("clusterset2"), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, allowUpdateClusterSets: map[string]bool{ @@ -202,13 +202,13 @@ func TestManagedClusterValidate(t *testing.T) { }, { name: "validate updating clusterset label without permission", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Update, + Operation: admissionv1.Update, OldObject: newManagedClusterObjWithClientSet("clusterset1"), Object: newManagedClusterObjWithClientSet("clusterset2"), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: false, Result: &metav1.Status{ Status: metav1.StatusFailure, Code: http.StatusForbidden, Reason: metav1.StatusReasonForbidden, @@ -218,13 +218,13 @@ func TestManagedClusterValidate(t *testing.T) { }, { name: "validate updating clusterset label with partial permission", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Update, + Operation: admissionv1.Update, OldObject: newManagedClusterObjWithClientSet("clusterset1"), Object: newManagedClusterObjWithClientSet("clusterset2"), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: false, Result: &metav1.Status{ Status: metav1.StatusFailure, Code: http.StatusForbidden, Reason: metav1.StatusReasonForbidden, @@ -237,13 +237,13 @@ func TestManagedClusterValidate(t *testing.T) { }, { name: "validate resetting clusterset label", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersSchema, - Operation: admissionv1beta1.Update, + Operation: admissionv1.Update, OldObject: newManagedClusterObjWithClientSet("clusterset1"), Object: newManagedClusterObjWithClientSet(""), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, allowUpdateClusterSets: map[string]bool{ diff --git a/pkg/webhook/clustersetbinding/validating_webhook.go b/pkg/webhook/clustersetbinding/validating_webhook.go index 02d033425..2c6994a08 100644 --- a/pkg/webhook/clustersetbinding/validating_webhook.go +++ b/pkg/webhook/clustersetbinding/validating_webhook.go @@ -7,7 +7,7 @@ import ( "net/http" clusterv1alpha1 "github.com/open-cluster-management/api/cluster/v1alpha1" - admissionv1beta1 "k8s.io/api/admission/v1beta1" + admissionv1 "k8s.io/api/admission/v1" authenticationv1 "k8s.io/api/authentication/v1" authorizationv1 "k8s.io/api/authorization/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -34,7 +34,7 @@ func (a *ManagedClusterSetBindingValidatingAdmissionHook) ValidatingResource() ( } // Validate is called by generic-admission-server when the registered REST resource above is called with an admission request. -func (a *ManagedClusterSetBindingValidatingAdmissionHook) Validate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse { +func (a *ManagedClusterSetBindingValidatingAdmissionHook) Validate(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse { klog.V(4).Infof("validate %q operation for object %q", admissionSpec.Operation, admissionSpec.Object) // only validate the request for ManagedClusterSetBinding @@ -44,7 +44,7 @@ func (a *ManagedClusterSetBindingValidatingAdmissionHook) Validate(admissionSpec } // only handle Create/Update Operation - if admissionSpec.Operation != admissionv1beta1.Create && admissionSpec.Operation != admissionv1beta1.Update { + if admissionSpec.Operation != admissionv1.Create && admissionSpec.Operation != admissionv1.Update { return acceptRequest() } @@ -61,7 +61,7 @@ func (a *ManagedClusterSetBindingValidatingAdmissionHook) Validate(admissionSpec } // check if the request user has permission to bind the target cluster set - if admissionSpec.Operation == admissionv1beta1.Create { + if admissionSpec.Operation == admissionv1.Create { return a.allowBindingToClusterSet(binding.Spec.ClusterSet, admissionSpec.UserInfo) } @@ -80,7 +80,7 @@ func (a *ManagedClusterSetBindingValidatingAdmissionHook) Initialize(kubeClientC } // allowBindingToClusterSet checks if the user has permission to bind a particular cluster set -func (a *ManagedClusterSetBindingValidatingAdmissionHook) allowBindingToClusterSet(clusterSetName string, userInfo authenticationv1.UserInfo) *admissionv1beta1.AdmissionResponse { +func (a *ManagedClusterSetBindingValidatingAdmissionHook) allowBindingToClusterSet(clusterSetName string, userInfo authenticationv1.UserInfo) *admissionv1.AdmissionResponse { extra := make(map[string]authorizationv1.ExtraValue) for k, v := range userInfo.Extra { extra[k] = authorizationv1.ExtraValue(v) @@ -111,14 +111,14 @@ func (a *ManagedClusterSetBindingValidatingAdmissionHook) allowBindingToClusterS return acceptRequest() } -func acceptRequest() *admissionv1beta1.AdmissionResponse { - return &admissionv1beta1.AdmissionResponse{ +func acceptRequest() *admissionv1.AdmissionResponse { + return &admissionv1.AdmissionResponse{ Allowed: true, } } -func denyRequest(code int32, reason metav1.StatusReason, message string) *admissionv1beta1.AdmissionResponse { - return &admissionv1beta1.AdmissionResponse{ +func denyRequest(code int32, reason metav1.StatusReason, message string) *admissionv1.AdmissionResponse { + return &admissionv1.AdmissionResponse{ Allowed: false, Result: &metav1.Status{ Status: metav1.StatusFailure, diff --git a/pkg/webhook/clustersetbinding/validating_webhook_test.go b/pkg/webhook/clustersetbinding/validating_webhook_test.go index 233f391b5..61aa6f767 100644 --- a/pkg/webhook/clustersetbinding/validating_webhook_test.go +++ b/pkg/webhook/clustersetbinding/validating_webhook_test.go @@ -7,7 +7,7 @@ import ( "testing" clusterv1alpha1 "github.com/open-cluster-management/api/cluster/v1alpha1" - admissionv1beta1 "k8s.io/api/admission/v1beta1" + admissionv1 "k8s.io/api/admission/v1" authorizationv1 "k8s.io/api/authorization/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -24,53 +24,53 @@ var managedclustersetbindingSchema = metav1.GroupVersionResource{ func TestManagedClusterValidate(t *testing.T) { cases := []struct { name string - request *admissionv1beta1.AdmissionRequest - expectedResponse *admissionv1beta1.AdmissionResponse + request *admissionv1.AdmissionRequest + expectedResponse *admissionv1.AdmissionResponse allowBindingToClusterSet bool }{ { name: "validate non-managedclustersetbindings request", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: metav1.GroupVersionResource{ Group: "test.open-cluster-management.io", Version: "v1", Resource: "tests", }, }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, }, { name: "validate deleting operation", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersetbindingSchema, - Operation: admissionv1beta1.Delete, + Operation: admissionv1.Delete, }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, }, { name: "validate creating cluster set binding", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersetbindingSchema, - Operation: admissionv1beta1.Create, + Operation: admissionv1.Create, Object: newManagedClusterSetBindingObj("ns1", "cs1", "cs1", nil), }, allowBindingToClusterSet: true, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, }, { name: "validate creating cluster set binding with unmatched name", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersetbindingSchema, - Operation: admissionv1beta1.Create, + Operation: admissionv1.Create, Object: newManagedClusterSetBindingObj("ns1", "csb1", "cs1", nil), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: false, Result: &metav1.Status{ Status: metav1.StatusFailure, Code: http.StatusBadRequest, Reason: metav1.StatusReasonBadRequest, @@ -80,12 +80,12 @@ func TestManagedClusterValidate(t *testing.T) { }, { name: "validate creating cluster set binding without permission", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersetbindingSchema, - Operation: admissionv1beta1.Create, + Operation: admissionv1.Create, Object: newManagedClusterSetBindingObj("ns1", "cs1", "cs1", nil), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: false, Result: &metav1.Status{ Status: metav1.StatusFailure, Code: http.StatusForbidden, Reason: metav1.StatusReasonForbidden, @@ -95,28 +95,28 @@ func TestManagedClusterValidate(t *testing.T) { }, { name: "validate updating cluster set binding", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersetbindingSchema, - Operation: admissionv1beta1.Update, + Operation: admissionv1.Update, Object: newManagedClusterSetBindingObj("ns1", "cs1", "cs1", nil), OldObject: newManagedClusterSetBindingObj("ns1", "cs1", "cs2", map[string]string{ "team": "team1", }), }, allowBindingToClusterSet: true, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: true, }, }, { name: "validate updating cluster set binding with different cluster set", - request: &admissionv1beta1.AdmissionRequest{ + request: &admissionv1.AdmissionRequest{ Resource: managedclustersetbindingSchema, - Operation: admissionv1beta1.Update, + Operation: admissionv1.Update, Object: newManagedClusterSetBindingObj("ns1", "cs1", "cs2", nil), OldObject: newManagedClusterSetBindingObj("ns1", "cs1", "cs1", nil), }, - expectedResponse: &admissionv1beta1.AdmissionResponse{ + expectedResponse: &admissionv1.AdmissionResponse{ Allowed: false, Result: &metav1.Status{ Status: metav1.StatusFailure, Code: http.StatusBadRequest, Reason: metav1.StatusReasonBadRequest, diff --git a/vendor/github.com/openshift/generic-admission-server/pkg/apiserver/apiserver.go b/vendor/github.com/openshift/generic-admission-server/pkg/apiserver/apiserver.go index fa6df5dd2..218c3ba78 100644 --- a/vendor/github.com/openshift/generic-admission-server/pkg/apiserver/apiserver.go +++ b/vendor/github.com/openshift/generic-admission-server/pkg/apiserver/apiserver.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + admissionv1 "k8s.io/api/admission/v1" admissionv1beta1 "k8s.io/api/admission/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -34,12 +35,24 @@ type ValidatingAdmissionHook interface { // MutatingAdmissionHook as well, the two resources for validating and mutating admission must be different. // Note: this is (usually) not the same as the payload resource! ValidatingResource() (plural schema.GroupVersionResource, singular string) +} + +type ValidatingAdmissionHookV1Beta1 interface { + ValidatingAdmissionHook // Validate is called to decide whether to accept the admission request. The returned AdmissionResponse // must not use the Patch field. Validate(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse } +type ValidatingAdmissionHookV1 interface { + ValidatingAdmissionHook + + // Validate is called to decide whether to accept the v1 admission request. The returned AdmissionResponse + // must not use the Patch field. + Validate(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse +} + type MutatingAdmissionHook interface { AdmissionHook @@ -47,13 +60,26 @@ type MutatingAdmissionHook interface { // ValidatingAdmissionHook as well, the two resources for validating and mutating admission must be different. // Note: this is (usually) not the same as the payload resource! MutatingResource() (plural schema.GroupVersionResource, singular string) +} + +type MutatingAdmissionHookV1Beta1 interface { + MutatingAdmissionHook // Admit is called to decide whether to accept the admission request. The returned AdmissionResponse may // use the Patch field to mutate the object from the passed AdmissionRequest. Admit(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse } +type MutatingAdmissionHookV1 interface { + MutatingAdmissionHook + + // Admit is called to decide whether to accept the v1 admission request. The returned AdmissionResponse may + // use the Patch field to mutate the object from the passed AdmissionRequest. + Admit(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse +} + func init() { + admissionv1.AddToScheme(Scheme) admissionv1beta1.AddToScheme(Scheme) // we need to add the options to empty v1 @@ -74,6 +100,7 @@ func init() { type Config struct { GenericConfig *genericapiserver.RecommendedConfig ExtraConfig ExtraConfig + RestConfig *restclient.Config } type ExtraConfig struct { @@ -88,6 +115,7 @@ type AdmissionServer struct { type completedConfig struct { GenericConfig genericapiserver.CompletedConfig ExtraConfig *ExtraConfig + RestConfig *restclient.Config } type CompletedConfig struct { @@ -100,6 +128,7 @@ func (c *Config) Complete() CompletedConfig { completedCfg := completedConfig{ c.GenericConfig.Complete(), &c.ExtraConfig, + c.RestConfig, } completedCfg.GenericConfig.Version = &version.Info{ @@ -121,9 +150,12 @@ func (c completedConfig) New() (*AdmissionServer, error) { GenericAPIServer: genericServer, } - inClusterConfig, err := restclient.InClusterConfig() - if err != nil { - return nil, err + restConfig := c.RestConfig + if restConfig == nil { + restConfig, err = restclient.InClusterConfig() + if err != nil { + return nil, err + } } for _, versionMap := range admissionHooksByGroupThenVersion(c.ExtraConfig.AdmissionHooks...) { @@ -147,7 +179,10 @@ func (c completedConfig) New() (*AdmissionServer, error) { // just overwrite the groupversion with a random one. We don't really care or know. apiGroupInfo.PrioritizedVersions = appendUniqueGroupVersion(apiGroupInfo.PrioritizedVersions, admissionVersion) - admissionReview := admissionreview.NewREST(admissionHook.Admission) + admissionReview := getAdmissionRest(admissionHook) + if admissionReview == nil { + continue + } v1alpha1storage, ok := apiGroupInfo.VersionedResourcesStorageMap[admissionVersion.Version] if !ok { v1alpha1storage = map[string]rest.Storage{} @@ -170,7 +205,7 @@ func (c completedConfig) New() (*AdmissionServer, error) { } s.GenericAPIServer.AddPostStartHookOrDie(postStartName, func(context genericapiserver.PostStartHookContext) error { - return admissionHook.Initialize(inClusterConfig, context.StopCh) + return admissionHook.Initialize(restConfig, context.StopCh) }, ) } @@ -213,55 +248,119 @@ func admissionHooksByGroupThenVersion(admissionHooks ...AdmissionHook) map[strin ret := map[string]map[string][]admissionHookWrapper{} for i := range admissionHooks { - if mutatingHook, ok := admissionHooks[i].(MutatingAdmissionHook); ok { + if mutatingHook, ok := admissionHooks[i].(MutatingAdmissionHookV1Beta1); ok { gvr, _ := mutatingHook.MutatingResource() group, ok := ret[gvr.Group] if !ok { group = map[string][]admissionHookWrapper{} ret[gvr.Group] = group } - group[gvr.Version] = append(group[gvr.Version], mutatingAdmissionHookWrapper{mutatingHook}) + group[gvr.Version] = append(group[gvr.Version], mutatingAdmissionHookV1Beta1Wrapper{hook: mutatingHook}) } - if validatingHook, ok := admissionHooks[i].(ValidatingAdmissionHook); ok { + if validatingHook, ok := admissionHooks[i].(ValidatingAdmissionHookV1Beta1); ok { gvr, _ := validatingHook.ValidatingResource() group, ok := ret[gvr.Group] if !ok { group = map[string][]admissionHookWrapper{} ret[gvr.Group] = group } - group[gvr.Version] = append(group[gvr.Version], validatingAdmissionHookWrapper{validatingHook}) + group[gvr.Version] = append(group[gvr.Version], validatingAdmissionHookV1Beta1Wrapper{hook: validatingHook}) + } + if mutatingHook, ok := admissionHooks[i].(MutatingAdmissionHookV1); ok { + gvr, _ := mutatingHook.MutatingResource() + group, ok := ret[gvr.Group] + if !ok { + group = map[string][]admissionHookWrapper{} + ret[gvr.Group] = group + } + group[gvr.Version] = append(group[gvr.Version], mutatingAdmissionHookV1Wrapper{hook: mutatingHook}) + } + if validatingHook, ok := admissionHooks[i].(ValidatingAdmissionHookV1); ok { + gvr, _ := validatingHook.ValidatingResource() + group, ok := ret[gvr.Group] + if !ok { + group = map[string][]admissionHookWrapper{} + ret[gvr.Group] = group + } + group[gvr.Version] = append(group[gvr.Version], validatingAdmissionHookV1Wrapper{hook: validatingHook}) } } return ret } +func getAdmissionRest(wrapper admissionHookWrapper) rest.Storage { + switch t := wrapper.(type) { + case admissionHookWrapperV1Alpha1: + return admissionreview.NewREST(t.Admission) + case admissionHookWrapperV1: + return admissionreview.NewV1REST(t.Admission) + } + + return nil +} + // admissionHookWrapper wraps either a validating or mutating admission hooks, calling the respective resource and admission method. type admissionHookWrapper interface { Resource() (plural schema.GroupVersionResource, singular string) +} + +type admissionHookWrapperV1Alpha1 interface { + admissionHookWrapper Admission(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse } -type mutatingAdmissionHookWrapper struct { - hook MutatingAdmissionHook +type admissionHookWrapperV1 interface { + admissionHookWrapper + Admission(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse +} + +// v1beta1 wrappers +type mutatingAdmissionHookV1Beta1Wrapper struct { + hook MutatingAdmissionHookV1Beta1 +} + +func (h mutatingAdmissionHookV1Beta1Wrapper) Resource() (plural schema.GroupVersionResource, singular string) { + return h.hook.MutatingResource() +} + +func (h mutatingAdmissionHookV1Beta1Wrapper) Admission(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse { + return h.hook.Admit(admissionSpec) +} + +type validatingAdmissionHookV1Beta1Wrapper struct { + hook ValidatingAdmissionHookV1Beta1 +} + +func (h validatingAdmissionHookV1Beta1Wrapper) Resource() (plural schema.GroupVersionResource, singular string) { + return h.hook.ValidatingResource() +} + +func (h validatingAdmissionHookV1Beta1Wrapper) Admission(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse { + return h.hook.Validate(admissionSpec) +} + +// v1 wrappers +type mutatingAdmissionHookV1Wrapper struct { + hook MutatingAdmissionHookV1 } -func (h mutatingAdmissionHookWrapper) Resource() (plural schema.GroupVersionResource, singular string) { +func (h mutatingAdmissionHookV1Wrapper) Resource() (plural schema.GroupVersionResource, singular string) { return h.hook.MutatingResource() } -func (h mutatingAdmissionHookWrapper) Admission(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse { +func (h mutatingAdmissionHookV1Wrapper) Admission(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse { return h.hook.Admit(admissionSpec) } -type validatingAdmissionHookWrapper struct { - hook ValidatingAdmissionHook +type validatingAdmissionHookV1Wrapper struct { + hook ValidatingAdmissionHookV1 } -func (h validatingAdmissionHookWrapper) Resource() (plural schema.GroupVersionResource, singular string) { +func (h validatingAdmissionHookV1Wrapper) Resource() (plural schema.GroupVersionResource, singular string) { return h.hook.ValidatingResource() } -func (h validatingAdmissionHookWrapper) Admission(admissionSpec *admissionv1beta1.AdmissionRequest) *admissionv1beta1.AdmissionResponse { +func (h validatingAdmissionHookV1Wrapper) Admission(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse { return h.hook.Validate(admissionSpec) } diff --git a/vendor/github.com/openshift/generic-admission-server/pkg/cmd/server/start.go b/vendor/github.com/openshift/generic-admission-server/pkg/cmd/server/start.go index 216df7cb3..5d2614c30 100644 --- a/vendor/github.com/openshift/generic-admission-server/pkg/cmd/server/start.go +++ b/vendor/github.com/openshift/generic-admission-server/pkg/cmd/server/start.go @@ -7,6 +7,7 @@ import ( "github.com/spf13/cobra" + admissionv1 "k8s.io/api/admission/v1" admissionv1beta1 "k8s.io/api/admission/v1beta1" genericapiserver "k8s.io/apiserver/pkg/server" genericoptions "k8s.io/apiserver/pkg/server/options" @@ -30,7 +31,7 @@ func NewAdmissionServerOptions(out, errOut io.Writer, admissionHooks ...apiserve // TODO we will nil out the etcd storage options. This requires a later level of k8s.io/apiserver RecommendedOptions: genericoptions.NewRecommendedOptions( defaultEtcdPathPrefix, - apiserver.Codecs.LegacyCodec(admissionv1beta1.SchemeGroupVersion), + apiserver.Codecs.LegacyCodec(admissionv1.SchemeGroupVersion, admissionv1beta1.SchemeGroupVersion), ), AdmissionHooks: admissionHooks, @@ -41,6 +42,12 @@ func NewAdmissionServerOptions(out, errOut io.Writer, admissionHooks ...apiserve o.RecommendedOptions.Etcd = nil o.RecommendedOptions.Admission = nil + // we can also optimize the authz options. We know that system:masters should always be authorized for actions and the + // delegating authorizer now allows this. + o.RecommendedOptions.Authorization = o.RecommendedOptions.Authorization. + WithAlwaysAllowPaths("/healthz", "/readyz", "/livez"). // this allows the kubelet to always get health and readiness without causing an access check + WithAlwaysAllowGroups("system:masters") // in a kube cluster, system:masters can take any action, so there is no need to ask for an authz check + return o } diff --git a/vendor/github.com/openshift/generic-admission-server/pkg/registry/admissionreview/admission_review_v1.go b/vendor/github.com/openshift/generic-admission-server/pkg/registry/admissionreview/admission_review_v1.go new file mode 100644 index 000000000..d032f1d78 --- /dev/null +++ b/vendor/github.com/openshift/generic-admission-server/pkg/registry/admissionreview/admission_review_v1.go @@ -0,0 +1,47 @@ +package admissionreview + +import ( + "context" + + admissionv1 "k8s.io/api/admission/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/registry/rest" +) + +type AdmissionV1HookFunc func(admissionSpec *admissionv1.AdmissionRequest) *admissionv1.AdmissionResponse + +type V1REST struct { + hookFn AdmissionV1HookFunc +} + +var _ rest.Creater = &REST{} +var _ rest.Scoper = &REST{} +var _ rest.GroupVersionKindProvider = &REST{} + +func NewV1REST(hookFn AdmissionV1HookFunc) *V1REST { + return &V1REST{ + hookFn: hookFn, + } +} + +func (r *V1REST) New() runtime.Object { + return &admissionv1.AdmissionReview{} +} + +func (r *V1REST) GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind { + return admissionv1.SchemeGroupVersion.WithKind("AdmissionReview") +} + +func (r *V1REST) NamespaceScoped() bool { + return false +} + +func (r *V1REST) Create(ctx context.Context, obj runtime.Object, _ rest.ValidateObjectFunc, _ *metav1.CreateOptions) (runtime.Object, error) { + admissionReview := obj.(*admissionv1.AdmissionReview) + admissionReview.Response = r.hookFn(admissionReview.Request) + // Copey request uid to response + admissionReview.Response.UID = admissionReview.Request.UID + return admissionReview, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 7ec959008..20e1e0ecb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -241,7 +241,7 @@ github.com/openshift/build-machinery-go/make/targets/golang github.com/openshift/build-machinery-go/make/targets/openshift github.com/openshift/build-machinery-go/make/targets/openshift/operator github.com/openshift/build-machinery-go/scripts -# github.com/openshift/generic-admission-server v1.14.1-0.20200903115324-4ddcdd976480 +# github.com/openshift/generic-admission-server v1.14.1-0.20210422140326-da96454c926d ## explicit github.com/openshift/generic-admission-server/pkg/apiserver github.com/openshift/generic-admission-server/pkg/cmd/server