diff --git a/pkg/registry/rbac/reconciliation/BUILD b/pkg/registry/rbac/reconciliation/BUILD index 79a1484a3d1..50c6dab9e05 100644 --- a/pkg/registry/rbac/reconciliation/BUILD +++ b/pkg/registry/rbac/reconciliation/BUILD @@ -11,8 +11,8 @@ load( go_test( name = "go_default_test", srcs = [ - "reconcile_clusterrolebindings_test.go", "reconcile_role_test.go", + "reconcile_rolebindings_test.go", ], library = ":go_default_library", tags = ["automanaged"], @@ -26,9 +26,12 @@ go_test( go_library( name = "go_default_library", srcs = [ - "reconcile_clusterrolebindings.go", + "clusterrole_interfaces.go", + "clusterrolebinding_interfaces.go", "reconcile_role.go", + "reconcile_rolebindings.go", "role_interfaces.go", + "rolebinding_interfaces.go", ], tags = ["automanaged"], deps = [ @@ -38,6 +41,7 @@ go_library( "//pkg/registry/rbac/validation:go_default_library", "//vendor:k8s.io/apimachinery/pkg/api/errors", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", + "//vendor:k8s.io/apimachinery/pkg/types", ], ) diff --git a/pkg/registry/rbac/reconciliation/clusterrole_interfaces.go b/pkg/registry/rbac/reconciliation/clusterrole_interfaces.go new file mode 100644 index 00000000000..93928b20c8e --- /dev/null +++ b/pkg/registry/rbac/reconciliation/clusterrole_interfaces.go @@ -0,0 +1,88 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package reconciliation + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/rbac" + "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion" +) + +type ClusterRoleRuleOwner struct { + ClusterRole *rbac.ClusterRole +} + +func (o ClusterRoleRuleOwner) GetNamespace() string { + return o.ClusterRole.Namespace +} + +func (o ClusterRoleRuleOwner) GetName() string { + return o.ClusterRole.Name +} + +func (o ClusterRoleRuleOwner) GetLabels() map[string]string { + return o.ClusterRole.Labels +} + +func (o ClusterRoleRuleOwner) SetLabels(in map[string]string) { + o.ClusterRole.Labels = in +} + +func (o ClusterRoleRuleOwner) GetAnnotations() map[string]string { + return o.ClusterRole.Annotations +} + +func (o ClusterRoleRuleOwner) SetAnnotations(in map[string]string) { + o.ClusterRole.Annotations = in +} + +func (o ClusterRoleRuleOwner) GetRules() []rbac.PolicyRule { + return o.ClusterRole.Rules +} + +func (o ClusterRoleRuleOwner) SetRules(in []rbac.PolicyRule) { + o.ClusterRole.Rules = in +} + +type ClusterRoleModifier struct { + Client internalversion.ClusterRoleInterface +} + +func (c ClusterRoleModifier) Get(namespace, name string) (RuleOwner, error) { + ret, err := c.Client.Get(name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + return ClusterRoleRuleOwner{ClusterRole: ret}, err +} + +func (c ClusterRoleModifier) Create(in RuleOwner) (RuleOwner, error) { + ret, err := c.Client.Create(in.(ClusterRoleRuleOwner).ClusterRole) + if err != nil { + return nil, err + } + return ClusterRoleRuleOwner{ClusterRole: ret}, err +} + +func (c ClusterRoleModifier) Update(in RuleOwner) (RuleOwner, error) { + ret, err := c.Client.Update(in.(ClusterRoleRuleOwner).ClusterRole) + if err != nil { + return nil, err + } + return ClusterRoleRuleOwner{ClusterRole: ret}, err + +} diff --git a/pkg/registry/rbac/reconciliation/clusterrolebinding_interfaces.go b/pkg/registry/rbac/reconciliation/clusterrolebinding_interfaces.go new file mode 100644 index 00000000000..79c392d6e91 --- /dev/null +++ b/pkg/registry/rbac/reconciliation/clusterrolebinding_interfaces.go @@ -0,0 +1,101 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package reconciliation + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/kubernetes/pkg/apis/rbac" + "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion" +) + +type ClusterRoleBindingAdapter struct { + ClusterRoleBinding *rbac.ClusterRoleBinding +} + +func (o ClusterRoleBindingAdapter) GetNamespace() string { + return o.ClusterRoleBinding.Namespace +} + +func (o ClusterRoleBindingAdapter) GetName() string { + return o.ClusterRoleBinding.Name +} + +func (o ClusterRoleBindingAdapter) GetUID() types.UID { + return o.ClusterRoleBinding.UID +} + +func (o ClusterRoleBindingAdapter) GetLabels() map[string]string { + return o.ClusterRoleBinding.Labels +} + +func (o ClusterRoleBindingAdapter) SetLabels(in map[string]string) { + o.ClusterRoleBinding.Labels = in +} + +func (o ClusterRoleBindingAdapter) GetAnnotations() map[string]string { + return o.ClusterRoleBinding.Annotations +} + +func (o ClusterRoleBindingAdapter) SetAnnotations(in map[string]string) { + o.ClusterRoleBinding.Annotations = in +} + +func (o ClusterRoleBindingAdapter) GetRoleRef() rbac.RoleRef { + return o.ClusterRoleBinding.RoleRef +} + +func (o ClusterRoleBindingAdapter) GetSubjects() []rbac.Subject { + return o.ClusterRoleBinding.Subjects +} + +func (o ClusterRoleBindingAdapter) SetSubjects(in []rbac.Subject) { + o.ClusterRoleBinding.Subjects = in +} + +type ClusterRoleBindingClientAdapter struct { + Client internalversion.ClusterRoleBindingInterface +} + +func (c ClusterRoleBindingClientAdapter) Get(namespace, name string) (RoleBinding, error) { + ret, err := c.Client.Get(name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + return ClusterRoleBindingAdapter{ClusterRoleBinding: ret}, err +} + +func (c ClusterRoleBindingClientAdapter) Create(in RoleBinding) (RoleBinding, error) { + ret, err := c.Client.Create(in.(ClusterRoleBindingAdapter).ClusterRoleBinding) + if err != nil { + return nil, err + } + return ClusterRoleBindingAdapter{ClusterRoleBinding: ret}, err +} + +func (c ClusterRoleBindingClientAdapter) Update(in RoleBinding) (RoleBinding, error) { + ret, err := c.Client.Update(in.(ClusterRoleBindingAdapter).ClusterRoleBinding) + if err != nil { + return nil, err + } + return ClusterRoleBindingAdapter{ClusterRoleBinding: ret}, err + +} + +func (c ClusterRoleBindingClientAdapter) Delete(namespace, name string, uid types.UID) error { + return c.Client.Delete(name, &metav1.DeleteOptions{Preconditions: &metav1.Preconditions{UID: &uid}}) +} diff --git a/pkg/registry/rbac/reconciliation/reconcile_role.go b/pkg/registry/rbac/reconciliation/reconcile_role.go index 03641c32db2..c29f105a14d 100644 --- a/pkg/registry/rbac/reconciliation/reconcile_role.go +++ b/pkg/registry/rbac/reconciliation/reconcile_role.go @@ -21,10 +21,8 @@ import ( "reflect" "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/rbac" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion" "k8s.io/kubernetes/pkg/registry/rbac/validation" ) @@ -54,7 +52,7 @@ type RuleOwner interface { SetRules([]rbac.PolicyRule) } -type ReconcileClusterRoleOptions struct { +type ReconcileRoleOptions struct { // Role is the expected role that will be reconciled Role RuleOwner // Confirm indicates writes should be performed. When false, results are returned as a dry-run. @@ -85,11 +83,11 @@ type ReconcileClusterRoleResult struct { Protected bool } -func (o *ReconcileClusterRoleOptions) Run() (*ReconcileClusterRoleResult, error) { +func (o *ReconcileRoleOptions) Run() (*ReconcileClusterRoleResult, error) { return o.run(0) } -func (o *ReconcileClusterRoleOptions) run(attempts int) (*ReconcileClusterRoleResult, error) { +func (o *ReconcileRoleOptions) run(attempts int) (*ReconcileClusterRoleResult, error) { // This keeps us from retrying forever if a role keeps appearing and disappearing as we reconcile. // Conflict errors on update are handled at a higher level. if attempts > 2 { @@ -215,68 +213,3 @@ func merge(maps ...map[string]string) map[string]string { } return output } - -type ClusterRoleRuleOwner struct { - ClusterRole *rbac.ClusterRole -} - -func (o ClusterRoleRuleOwner) GetNamespace() string { - return o.ClusterRole.Namespace -} - -func (o ClusterRoleRuleOwner) GetName() string { - return o.ClusterRole.Name -} - -func (o ClusterRoleRuleOwner) GetLabels() map[string]string { - return o.ClusterRole.Labels -} - -func (o ClusterRoleRuleOwner) SetLabels(in map[string]string) { - o.ClusterRole.Labels = in -} - -func (o ClusterRoleRuleOwner) GetAnnotations() map[string]string { - return o.ClusterRole.Annotations -} - -func (o ClusterRoleRuleOwner) SetAnnotations(in map[string]string) { - o.ClusterRole.Annotations = in -} - -func (o ClusterRoleRuleOwner) GetRules() []rbac.PolicyRule { - return o.ClusterRole.Rules -} - -func (o ClusterRoleRuleOwner) SetRules(in []rbac.PolicyRule) { - o.ClusterRole.Rules = in -} - -type ClusterRoleModifier struct { - Client internalversion.ClusterRoleInterface -} - -func (c ClusterRoleModifier) Get(namespace, name string) (RuleOwner, error) { - ret, err := c.Client.Get(name, metav1.GetOptions{}) - if err != nil { - return nil, err - } - return ClusterRoleRuleOwner{ClusterRole: ret}, err -} - -func (c ClusterRoleModifier) Create(in RuleOwner) (RuleOwner, error) { - ret, err := c.Client.Create(in.(ClusterRoleRuleOwner).ClusterRole) - if err != nil { - return nil, err - } - return ClusterRoleRuleOwner{ClusterRole: ret}, err -} - -func (c ClusterRoleModifier) Update(in RuleOwner) (RuleOwner, error) { - ret, err := c.Client.Create(in.(ClusterRoleRuleOwner).ClusterRole) - if err != nil { - return nil, err - } - return ClusterRoleRuleOwner{ClusterRole: ret}, err - -} diff --git a/pkg/registry/rbac/reconciliation/reconcile_clusterrolebindings.go b/pkg/registry/rbac/reconciliation/reconcile_rolebindings.go similarity index 74% rename from pkg/registry/rbac/reconciliation/reconcile_clusterrolebindings.go rename to pkg/registry/rbac/reconciliation/reconcile_rolebindings.go index fb4d406ecc5..fcb6eac61d9 100644 --- a/pkg/registry/rbac/reconciliation/reconcile_clusterrolebindings.go +++ b/pkg/registry/rbac/reconciliation/reconcile_rolebindings.go @@ -21,29 +21,48 @@ import ( "reflect" "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/apis/rbac" - "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion" ) -// ReconcileClusterRoleBindingOptions holds options for running a role binding reconciliation -type ReconcileClusterRoleBindingOptions struct { +type RoleBindingModifier interface { + Get(namespace, name string) (RoleBinding, error) + Delete(namespace, name string, uid types.UID) error + Create(RoleBinding) (RoleBinding, error) + Update(RoleBinding) (RoleBinding, error) +} + +type RoleBinding interface { + GetNamespace() string + GetName() string + GetUID() types.UID + GetLabels() map[string]string + SetLabels(map[string]string) + GetAnnotations() map[string]string + SetAnnotations(map[string]string) + GetRoleRef() rbac.RoleRef + GetSubjects() []rbac.Subject + SetSubjects([]rbac.Subject) +} + +// ReconcileRoleBindingOptions holds options for running a role binding reconciliation +type ReconcileRoleBindingOptions struct { // RoleBinding is the expected rolebinding that will be reconciled - RoleBinding *rbac.ClusterRoleBinding + RoleBinding RoleBinding // Confirm indicates writes should be performed. When false, results are returned as a dry-run. Confirm bool // RemoveExtraSubjects indicates reconciliation should remove extra subjects from an existing role binding RemoveExtraSubjects bool // Client is used to look up existing rolebindings, and create/update the rolebinding when Confirm=true - Client internalversion.ClusterRoleBindingInterface + Client RoleBindingModifier } // ReconcileClusterRoleBindingResult holds the result of a reconciliation operation. type ReconcileClusterRoleBindingResult struct { // RoleBinding is the reconciled rolebinding from the reconciliation operation. // If the reconcile was performed as a dry-run, or the existing rolebinding was protected, the reconciled rolebinding is not persisted. - RoleBinding *rbac.ClusterRoleBinding + RoleBinding RoleBinding // MissingSubjects contains expected subjects that were missing from the currently persisted rolebinding MissingSubjects []rbac.Subject @@ -60,11 +79,11 @@ type ReconcileClusterRoleBindingResult struct { Protected bool } -func (o *ReconcileClusterRoleBindingOptions) Run() (*ReconcileClusterRoleBindingResult, error) { +func (o *ReconcileRoleBindingOptions) Run() (*ReconcileClusterRoleBindingResult, error) { return o.run(0) } -func (o *ReconcileClusterRoleBindingOptions) run(attempts int) (*ReconcileClusterRoleBindingResult, error) { +func (o *ReconcileRoleBindingOptions) run(attempts int) (*ReconcileClusterRoleBindingResult, error) { // This keeps us from retrying forever if a rolebinding keeps appearing and disappearing as we reconcile. // Conflict errors on update are handled at a higher level. if attempts > 3 { @@ -73,12 +92,12 @@ func (o *ReconcileClusterRoleBindingOptions) run(attempts int) (*ReconcileCluste var result *ReconcileClusterRoleBindingResult - existingBinding, err := o.Client.Get(o.RoleBinding.Name, metav1.GetOptions{}) + existingBinding, err := o.Client.Get(o.RoleBinding.GetNamespace(), o.RoleBinding.GetName()) switch { case errors.IsNotFound(err): result = &ReconcileClusterRoleBindingResult{ RoleBinding: o.RoleBinding, - MissingSubjects: o.RoleBinding.Subjects, + MissingSubjects: o.RoleBinding.GetSubjects(), Operation: ReconcileCreate, } @@ -104,10 +123,7 @@ func (o *ReconcileClusterRoleBindingOptions) run(attempts int) (*ReconcileCluste switch result.Operation { case ReconcileRecreate: // Try deleting - err := o.Client.Delete( - existingBinding.Name, - &metav1.DeleteOptions{Preconditions: &metav1.Preconditions{UID: &existingBinding.UID}}, - ) + err := o.Client.Delete(existingBinding.GetNamespace(), existingBinding.GetName(), existingBinding.GetUID()) switch { case err == nil, errors.IsNotFound(err): // object no longer exists, as desired @@ -155,13 +171,13 @@ func (o *ReconcileClusterRoleBindingOptions) run(attempts int) (*ReconcileCluste // computeReconciledRoleBinding returns the rolebinding that must be created and/or updated to make the // existing rolebinding's subjects, roleref, labels, and annotations match the expected rolebinding -func computeReconciledRoleBinding(existing, expected *rbac.ClusterRoleBinding, removeExtraSubjects bool) (*ReconcileClusterRoleBindingResult, error) { +func computeReconciledRoleBinding(existing, expected RoleBinding, removeExtraSubjects bool) (*ReconcileClusterRoleBindingResult, error) { result := &ReconcileClusterRoleBindingResult{Operation: ReconcileNone} - result.Protected = (existing.Annotations[rbac.AutoUpdateAnnotationKey] == "false") + result.Protected = (existing.GetAnnotations()[rbac.AutoUpdateAnnotationKey] == "false") // Reset the binding completely if the roleRef is different - if expected.RoleRef != existing.RoleRef { + if expected.GetRoleRef() != existing.GetRoleRef() { result.RoleBinding = expected result.Operation = ReconcileRecreate return result, nil @@ -172,30 +188,30 @@ func computeReconciledRoleBinding(existing, expected *rbac.ClusterRoleBinding, r if err != nil { return nil, err } - result.RoleBinding = changedObj.(*rbac.ClusterRoleBinding) + result.RoleBinding = changedObj.(RoleBinding) // Merge expected annotations and labels - result.RoleBinding.Annotations = merge(expected.Annotations, result.RoleBinding.Annotations) - if !reflect.DeepEqual(result.RoleBinding.Annotations, existing.Annotations) { + result.RoleBinding.SetAnnotations(merge(expected.GetAnnotations(), result.RoleBinding.GetAnnotations())) + if !reflect.DeepEqual(result.RoleBinding.GetAnnotations(), existing.GetAnnotations()) { result.Operation = ReconcileUpdate } - result.RoleBinding.Labels = merge(expected.Labels, result.RoleBinding.Labels) - if !reflect.DeepEqual(result.RoleBinding.Labels, existing.Labels) { + result.RoleBinding.SetLabels(merge(expected.GetLabels(), result.RoleBinding.GetLabels())) + if !reflect.DeepEqual(result.RoleBinding.GetLabels(), existing.GetLabels()) { result.Operation = ReconcileUpdate } // Compute extra and missing subjects - result.MissingSubjects, result.ExtraSubjects = diffSubjectLists(expected.Subjects, existing.Subjects) + result.MissingSubjects, result.ExtraSubjects = diffSubjectLists(expected.GetSubjects(), existing.GetSubjects()) switch { case !removeExtraSubjects && len(result.MissingSubjects) > 0: // add missing subjects in the union case - result.RoleBinding.Subjects = append(result.RoleBinding.Subjects, result.MissingSubjects...) + result.RoleBinding.SetSubjects(append(result.RoleBinding.GetSubjects(), result.MissingSubjects...)) result.Operation = ReconcileUpdate case removeExtraSubjects && (len(result.MissingSubjects) > 0 || len(result.ExtraSubjects) > 0): // stomp to expected subjects in the non-union case - result.RoleBinding.Subjects = expected.Subjects + result.RoleBinding.SetSubjects(expected.GetSubjects()) result.Operation = ReconcileUpdate } diff --git a/pkg/registry/rbac/reconciliation/reconcile_clusterrolebindings_test.go b/pkg/registry/rbac/reconciliation/reconcile_rolebindings_test.go similarity index 93% rename from pkg/registry/rbac/reconciliation/reconcile_clusterrolebindings_test.go rename to pkg/registry/rbac/reconciliation/reconcile_rolebindings_test.go index e0839f94b6a..9a69e9136bf 100644 --- a/pkg/registry/rbac/reconciliation/reconcile_clusterrolebindings_test.go +++ b/pkg/registry/rbac/reconciliation/reconcile_rolebindings_test.go @@ -161,13 +161,15 @@ func TestComputeUpdate(t *testing.T) { } for k, tc := range tests { - result, err := computeReconciledRoleBinding(tc.ActualBinding, tc.ExpectedBinding, tc.RemoveExtraSubjects) + actualRoleBinding := ClusterRoleBindingAdapter{ClusterRoleBinding: tc.ActualBinding} + expectedRoleBinding := ClusterRoleBindingAdapter{ClusterRoleBinding: tc.ExpectedBinding} + result, err := computeReconciledRoleBinding(actualRoleBinding, expectedRoleBinding, tc.RemoveExtraSubjects) if err != nil { t.Errorf("%s: %v", k, err) continue } updateNeeded := result.Operation != ReconcileNone - updatedBinding := result.RoleBinding + updatedBinding := result.RoleBinding.(ClusterRoleBindingAdapter).ClusterRoleBinding if updateNeeded != tc.ExpectedUpdateNeeded { t.Errorf("%s: Expected\n\t%v\ngot\n\t%v (%v)", k, tc.ExpectedUpdateNeeded, updateNeeded, result.Operation) continue diff --git a/pkg/registry/rbac/reconciliation/role_interfaces.go b/pkg/registry/rbac/reconciliation/role_interfaces.go index 05887cc0c83..b3bc3c882b0 100644 --- a/pkg/registry/rbac/reconciliation/role_interfaces.go +++ b/pkg/registry/rbac/reconciliation/role_interfaces.go @@ -79,7 +79,7 @@ func (c RoleModifier) Create(in RuleOwner) (RuleOwner, error) { } func (c RoleModifier) Update(in RuleOwner) (RuleOwner, error) { - ret, err := c.Client.Roles(in.GetNamespace()).Create(in.(RoleRuleOwner).Role) + ret, err := c.Client.Roles(in.GetNamespace()).Update(in.(RoleRuleOwner).Role) if err != nil { return nil, err } diff --git a/pkg/registry/rbac/reconciliation/rolebinding_interfaces.go b/pkg/registry/rbac/reconciliation/rolebinding_interfaces.go new file mode 100644 index 00000000000..6ec14ab2dbf --- /dev/null +++ b/pkg/registry/rbac/reconciliation/rolebinding_interfaces.go @@ -0,0 +1,101 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package reconciliation + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/kubernetes/pkg/apis/rbac" + "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion" +) + +type RoleBindingAdapter struct { + RoleBinding *rbac.RoleBinding +} + +func (o RoleBindingAdapter) GetNamespace() string { + return o.RoleBinding.Namespace +} + +func (o RoleBindingAdapter) GetName() string { + return o.RoleBinding.Name +} + +func (o RoleBindingAdapter) GetUID() types.UID { + return o.RoleBinding.UID +} + +func (o RoleBindingAdapter) GetLabels() map[string]string { + return o.RoleBinding.Labels +} + +func (o RoleBindingAdapter) SetLabels(in map[string]string) { + o.RoleBinding.Labels = in +} + +func (o RoleBindingAdapter) GetAnnotations() map[string]string { + return o.RoleBinding.Annotations +} + +func (o RoleBindingAdapter) SetAnnotations(in map[string]string) { + o.RoleBinding.Annotations = in +} + +func (o RoleBindingAdapter) GetRoleRef() rbac.RoleRef { + return o.RoleBinding.RoleRef +} + +func (o RoleBindingAdapter) GetSubjects() []rbac.Subject { + return o.RoleBinding.Subjects +} + +func (o RoleBindingAdapter) SetSubjects(in []rbac.Subject) { + o.RoleBinding.Subjects = in +} + +type RoleBindingClientAdapter struct { + Client internalversion.RoleBindingsGetter +} + +func (c RoleBindingClientAdapter) Get(namespace, name string) (RoleBinding, error) { + ret, err := c.Client.RoleBindings(namespace).Get(name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + return RoleBindingAdapter{RoleBinding: ret}, err +} + +func (c RoleBindingClientAdapter) Create(in RoleBinding) (RoleBinding, error) { + ret, err := c.Client.RoleBindings(in.GetNamespace()).Create(in.(RoleBindingAdapter).RoleBinding) + if err != nil { + return nil, err + } + return RoleBindingAdapter{RoleBinding: ret}, err +} + +func (c RoleBindingClientAdapter) Update(in RoleBinding) (RoleBinding, error) { + ret, err := c.Client.RoleBindings(in.GetNamespace()).Update(in.(RoleBindingAdapter).RoleBinding) + if err != nil { + return nil, err + } + return RoleBindingAdapter{RoleBinding: ret}, err + +} + +func (c RoleBindingClientAdapter) Delete(namespace, name string, uid types.UID) error { + return c.Client.RoleBindings(namespace).Delete(name, &metav1.DeleteOptions{Preconditions: &metav1.Preconditions{UID: &uid}}) +} diff --git a/pkg/registry/rbac/rest/storage_rbac.go b/pkg/registry/rbac/rest/storage_rbac.go index 583270ab4c7..981a02433ef 100644 --- a/pkg/registry/rbac/rest/storage_rbac.go +++ b/pkg/registry/rbac/rest/storage_rbac.go @@ -147,7 +147,7 @@ func PostStartHook(hookContext genericapiserver.PostStartHookContext) error { // ensure bootstrap roles are created or reconciled for _, clusterRole := range append(bootstrappolicy.ClusterRoles(), bootstrappolicy.ControllerRoles()...) { - opts := reconciliation.ReconcileClusterRoleOptions{ + opts := reconciliation.ReconcileRoleOptions{ Role: reconciliation.ClusterRoleRuleOwner{ClusterRole: &clusterRole}, Client: reconciliation.ClusterRoleModifier{Client: clientset.ClusterRoles()}, Confirm: true, @@ -175,9 +175,9 @@ func PostStartHook(hookContext genericapiserver.PostStartHookContext) error { // ensure bootstrap rolebindings are created or reconciled for _, clusterRoleBinding := range append(bootstrappolicy.ClusterRoleBindings(), bootstrappolicy.ControllerRoleBindings()...) { - opts := reconciliation.ReconcileClusterRoleBindingOptions{ - RoleBinding: &clusterRoleBinding, - Client: clientset.ClusterRoleBindings(), + opts := reconciliation.ReconcileRoleBindingOptions{ + RoleBinding: reconciliation.ClusterRoleBindingAdapter{ClusterRoleBinding: &clusterRoleBinding}, + Client: reconciliation.ClusterRoleBindingClientAdapter{Client: clientset.ClusterRoleBindings()}, Confirm: true, } err := retry.RetryOnConflict(retry.DefaultBackoff, func() error { @@ -206,7 +206,7 @@ func PostStartHook(hookContext genericapiserver.PostStartHookContext) error { // ensure bootstrap namespaced roles are created or reconciled for namespace, roles := range bootstrappolicy.NamespaceRoles() { for _, role := range roles { - opts := reconciliation.ReconcileClusterRoleOptions{ + opts := reconciliation.ReconcileRoleOptions{ Role: reconciliation.RoleRuleOwner{Role: &role}, Client: reconciliation.RoleModifier{Client: clientset}, Confirm: true,