mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 18:43:34 +00:00
vendor files
This commit is contained in:
62
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/BUILD
generated
vendored
Normal file
62
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/BUILD
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"reconcile_role_test.go",
|
||||
"reconcile_rolebindings_test.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/registry/rbac/reconciliation",
|
||||
library = ":go_default_library",
|
||||
deps = [
|
||||
"//pkg/apis/core/helper:go_default_library",
|
||||
"//pkg/apis/rbac:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"clusterrole_interfaces.go",
|
||||
"clusterrolebinding_interfaces.go",
|
||||
"reconcile_role.go",
|
||||
"reconcile_rolebindings.go",
|
||||
"role_interfaces.go",
|
||||
"rolebinding_interfaces.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/registry/rbac/reconciliation",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/rbac:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion:go_default_library",
|
||||
"//pkg/registry/rbac/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
104
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/clusterrole_interfaces.go
generated
vendored
Normal file
104
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/clusterrole_interfaces.go
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
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/runtime"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/pkg/registry/rbac/reconciliation.RuleOwner
|
||||
// +k8s:deepcopy-gen:nonpointer-interfaces=true
|
||||
type ClusterRoleRuleOwner struct {
|
||||
ClusterRole *rbac.ClusterRole
|
||||
}
|
||||
|
||||
func (o ClusterRoleRuleOwner) GetObject() runtime.Object {
|
||||
return o.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
|
||||
}
|
||||
|
||||
func (o ClusterRoleRuleOwner) GetAggregationRule() *rbac.AggregationRule {
|
||||
return o.ClusterRole.AggregationRule
|
||||
}
|
||||
|
||||
func (o ClusterRoleRuleOwner) SetAggregationRule(in *rbac.AggregationRule) {
|
||||
o.ClusterRole.AggregationRule = 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
|
||||
|
||||
}
|
109
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/clusterrolebinding_interfaces.go
generated
vendored
Normal file
109
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/clusterrolebinding_interfaces.go
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
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/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/pkg/registry/rbac/reconciliation.RoleBinding
|
||||
// +k8s:deepcopy-gen:nonpointer-interfaces=true
|
||||
type ClusterRoleBindingAdapter struct {
|
||||
ClusterRoleBinding *rbac.ClusterRoleBinding
|
||||
}
|
||||
|
||||
func (o ClusterRoleBindingAdapter) GetObject() runtime.Object {
|
||||
return o.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}})
|
||||
}
|
281
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/reconcile_role.go
generated
vendored
Normal file
281
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/reconcile_role.go
generated
vendored
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
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 (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
"k8s.io/kubernetes/pkg/registry/rbac/validation"
|
||||
)
|
||||
|
||||
type ReconcileOperation string
|
||||
|
||||
var (
|
||||
ReconcileCreate ReconcileOperation = "create"
|
||||
ReconcileUpdate ReconcileOperation = "update"
|
||||
ReconcileRecreate ReconcileOperation = "recreate"
|
||||
ReconcileNone ReconcileOperation = "none"
|
||||
)
|
||||
|
||||
type RuleOwnerModifier interface {
|
||||
Get(namespace, name string) (RuleOwner, error)
|
||||
Create(RuleOwner) (RuleOwner, error)
|
||||
Update(RuleOwner) (RuleOwner, error)
|
||||
}
|
||||
|
||||
type RuleOwner interface {
|
||||
GetObject() runtime.Object
|
||||
GetNamespace() string
|
||||
GetName() string
|
||||
GetLabels() map[string]string
|
||||
SetLabels(map[string]string)
|
||||
GetAnnotations() map[string]string
|
||||
SetAnnotations(map[string]string)
|
||||
GetRules() []rbac.PolicyRule
|
||||
SetRules([]rbac.PolicyRule)
|
||||
GetAggregationRule() *rbac.AggregationRule
|
||||
SetAggregationRule(*rbac.AggregationRule)
|
||||
DeepCopyRuleOwner() RuleOwner
|
||||
}
|
||||
|
||||
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.
|
||||
Confirm bool
|
||||
// RemoveExtraPermissions indicates reconciliation should remove extra permissions from an existing role
|
||||
RemoveExtraPermissions bool
|
||||
// Client is used to look up existing roles, and create/update the role when Confirm=true
|
||||
Client RuleOwnerModifier
|
||||
}
|
||||
|
||||
type ReconcileClusterRoleResult struct {
|
||||
// Role is the reconciled role from the reconciliation operation.
|
||||
// If the reconcile was performed as a dry-run, or the existing role was protected, the reconciled role is not persisted.
|
||||
Role RuleOwner
|
||||
|
||||
// MissingRules contains expected rules that were missing from the currently persisted role
|
||||
MissingRules []rbac.PolicyRule
|
||||
// ExtraRules contains extra permissions the currently persisted role had
|
||||
ExtraRules []rbac.PolicyRule
|
||||
|
||||
// MissingAggregationRuleSelectors contains expected selectors that were missing from the currently persisted role
|
||||
MissingAggregationRuleSelectors []metav1.LabelSelector
|
||||
// ExtraAggregationRuleSelectors contains extra selectors the currently persisted role had
|
||||
ExtraAggregationRuleSelectors []metav1.LabelSelector
|
||||
|
||||
// Operation is the API operation required to reconcile.
|
||||
// If no reconciliation was needed, it is set to ReconcileNone.
|
||||
// If options.Confirm == false, the reconcile was in dry-run mode, so the operation was not performed.
|
||||
// If result.Protected == true, the role opted out of reconciliation, so the operation was not performed.
|
||||
// Otherwise, the operation was performed.
|
||||
Operation ReconcileOperation
|
||||
// Protected indicates an existing role prevented reconciliation
|
||||
Protected bool
|
||||
}
|
||||
|
||||
func (o *ReconcileRoleOptions) Run() (*ReconcileClusterRoleResult, error) {
|
||||
return o.run(0)
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, fmt.Errorf("exceeded maximum attempts")
|
||||
}
|
||||
|
||||
var result *ReconcileClusterRoleResult
|
||||
|
||||
existing, err := o.Client.Get(o.Role.GetNamespace(), o.Role.GetName())
|
||||
switch {
|
||||
case errors.IsNotFound(err):
|
||||
aggregationRule := o.Role.GetAggregationRule()
|
||||
if aggregationRule == nil {
|
||||
aggregationRule = &rbac.AggregationRule{}
|
||||
}
|
||||
result = &ReconcileClusterRoleResult{
|
||||
Role: o.Role,
|
||||
MissingRules: o.Role.GetRules(),
|
||||
MissingAggregationRuleSelectors: aggregationRule.ClusterRoleSelectors,
|
||||
Operation: ReconcileCreate,
|
||||
}
|
||||
|
||||
case err != nil:
|
||||
return nil, err
|
||||
|
||||
default:
|
||||
result, err = computeReconciledRole(existing, o.Role, o.RemoveExtraPermissions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// If reconcile-protected, short-circuit
|
||||
if result.Protected {
|
||||
return result, nil
|
||||
}
|
||||
// If we're in dry-run mode, short-circuit
|
||||
if !o.Confirm {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
switch result.Operation {
|
||||
case ReconcileCreate:
|
||||
created, err := o.Client.Create(result.Role)
|
||||
// If created since we started this reconcile, re-run
|
||||
if errors.IsAlreadyExists(err) {
|
||||
return o.run(attempts + 1)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.Role = created
|
||||
|
||||
case ReconcileUpdate:
|
||||
updated, err := o.Client.Update(result.Role)
|
||||
// If deleted since we started this reconcile, re-run
|
||||
if errors.IsNotFound(err) {
|
||||
return o.run(attempts + 1)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.Role = updated
|
||||
|
||||
case ReconcileNone:
|
||||
// no-op
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid operation: %v", result.Operation)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// computeReconciledRole returns the role that must be created and/or updated to make the
|
||||
// existing role's permissions match the expected role's permissions
|
||||
func computeReconciledRole(existing, expected RuleOwner, removeExtraPermissions bool) (*ReconcileClusterRoleResult, error) {
|
||||
result := &ReconcileClusterRoleResult{Operation: ReconcileNone}
|
||||
|
||||
result.Protected = (existing.GetAnnotations()[rbac.AutoUpdateAnnotationKey] == "false")
|
||||
|
||||
// Start with a copy of the existing object
|
||||
result.Role = existing.DeepCopyRuleOwner()
|
||||
|
||||
// Merge expected annotations and labels
|
||||
result.Role.SetAnnotations(merge(expected.GetAnnotations(), result.Role.GetAnnotations()))
|
||||
if !reflect.DeepEqual(result.Role.GetAnnotations(), existing.GetAnnotations()) {
|
||||
result.Operation = ReconcileUpdate
|
||||
}
|
||||
result.Role.SetLabels(merge(expected.GetLabels(), result.Role.GetLabels()))
|
||||
if !reflect.DeepEqual(result.Role.GetLabels(), existing.GetLabels()) {
|
||||
result.Operation = ReconcileUpdate
|
||||
}
|
||||
|
||||
// Compute extra and missing rules
|
||||
_, result.ExtraRules = validation.Covers(expected.GetRules(), existing.GetRules())
|
||||
_, result.MissingRules = validation.Covers(existing.GetRules(), expected.GetRules())
|
||||
|
||||
switch {
|
||||
case !removeExtraPermissions && len(result.MissingRules) > 0:
|
||||
// add missing rules in the union case
|
||||
result.Role.SetRules(append(result.Role.GetRules(), result.MissingRules...))
|
||||
result.Operation = ReconcileUpdate
|
||||
|
||||
case removeExtraPermissions && (len(result.MissingRules) > 0 || len(result.ExtraRules) > 0):
|
||||
// stomp to expected rules in the non-union case
|
||||
result.Role.SetRules(expected.GetRules())
|
||||
result.Operation = ReconcileUpdate
|
||||
}
|
||||
|
||||
// Compute extra and missing rules
|
||||
_, result.ExtraAggregationRuleSelectors = aggregationRuleCovers(expected.GetAggregationRule(), existing.GetAggregationRule())
|
||||
_, result.MissingAggregationRuleSelectors = aggregationRuleCovers(existing.GetAggregationRule(), expected.GetAggregationRule())
|
||||
|
||||
switch {
|
||||
case !removeExtraPermissions && len(result.MissingAggregationRuleSelectors) > 0:
|
||||
// add missing rules in the union case
|
||||
aggregationRule := result.Role.GetAggregationRule()
|
||||
if aggregationRule == nil {
|
||||
aggregationRule = &rbac.AggregationRule{}
|
||||
}
|
||||
aggregationRule.ClusterRoleSelectors = append(aggregationRule.ClusterRoleSelectors, result.MissingAggregationRuleSelectors...)
|
||||
result.Role.SetAggregationRule(aggregationRule)
|
||||
result.Operation = ReconcileUpdate
|
||||
|
||||
case removeExtraPermissions && (len(result.MissingAggregationRuleSelectors) > 0 || len(result.ExtraAggregationRuleSelectors) > 0):
|
||||
result.Role.SetAggregationRule(expected.GetAggregationRule())
|
||||
result.Operation = ReconcileUpdate
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// merge combines the given maps with the later annotations having higher precedence
|
||||
func merge(maps ...map[string]string) map[string]string {
|
||||
var output map[string]string = nil
|
||||
for _, m := range maps {
|
||||
if m != nil && output == nil {
|
||||
output = map[string]string{}
|
||||
}
|
||||
for k, v := range m {
|
||||
output[k] = v
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
// aggregationRuleCovers determines whether or not the ownerSelectors cover the servantSelectors in terms of semantically
|
||||
// equal label selectors.
|
||||
// It returns whether or not the ownerSelectors cover and a list of the rules that the ownerSelectors do not cover.
|
||||
func aggregationRuleCovers(ownerRule, servantRule *rbac.AggregationRule) (bool, []metav1.LabelSelector) {
|
||||
switch {
|
||||
case ownerRule == nil && servantRule == nil:
|
||||
return true, []metav1.LabelSelector{}
|
||||
case ownerRule == nil && servantRule != nil:
|
||||
return false, servantRule.ClusterRoleSelectors
|
||||
case ownerRule != nil && servantRule == nil:
|
||||
return true, []metav1.LabelSelector{}
|
||||
|
||||
}
|
||||
|
||||
ownerSelectors := ownerRule.ClusterRoleSelectors
|
||||
servantSelectors := servantRule.ClusterRoleSelectors
|
||||
uncoveredSelectors := []metav1.LabelSelector{}
|
||||
|
||||
for _, servantSelector := range servantSelectors {
|
||||
covered := false
|
||||
for _, ownerSelector := range ownerSelectors {
|
||||
if equality.Semantic.DeepEqual(ownerSelector, servantSelector) {
|
||||
covered = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !covered {
|
||||
uncoveredSelectors = append(uncoveredSelectors, servantSelector)
|
||||
}
|
||||
}
|
||||
|
||||
return (len(uncoveredSelectors) == 0), uncoveredSelectors
|
||||
}
|
372
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/reconcile_role_test.go
generated
vendored
Normal file
372
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/reconcile_role_test.go
generated
vendored
Normal file
@ -0,0 +1,372 @@
|
||||
/*
|
||||
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 (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
)
|
||||
|
||||
func role(rules []rbac.PolicyRule, labels map[string]string, annotations map[string]string) *rbac.ClusterRole {
|
||||
return &rbac.ClusterRole{
|
||||
Rules: rules,
|
||||
ObjectMeta: metav1.ObjectMeta{Labels: labels, Annotations: annotations},
|
||||
}
|
||||
}
|
||||
|
||||
func rules(resources ...string) []rbac.PolicyRule {
|
||||
r := []rbac.PolicyRule{}
|
||||
for _, resource := range resources {
|
||||
r = append(r, rbac.PolicyRule{APIGroups: []string{""}, Verbs: []string{"get"}, Resources: []string{resource}})
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
type ss map[string]string
|
||||
|
||||
func TestComputeReconciledRoleRules(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
expectedRole *rbac.ClusterRole
|
||||
actualRole *rbac.ClusterRole
|
||||
removeExtraPermissions bool
|
||||
|
||||
expectedReconciledRole *rbac.ClusterRole
|
||||
expectedReconciliationNeeded bool
|
||||
}{
|
||||
"empty": {
|
||||
expectedRole: role(rules(), nil, nil),
|
||||
actualRole: role(rules(), nil, nil),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: nil,
|
||||
expectedReconciliationNeeded: false,
|
||||
},
|
||||
"match without union": {
|
||||
expectedRole: role(rules("a"), nil, nil),
|
||||
actualRole: role(rules("a"), nil, nil),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: nil,
|
||||
expectedReconciliationNeeded: false,
|
||||
},
|
||||
"match with union": {
|
||||
expectedRole: role(rules("a"), nil, nil),
|
||||
actualRole: role(rules("a"), nil, nil),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: nil,
|
||||
expectedReconciliationNeeded: false,
|
||||
},
|
||||
"different rules without union": {
|
||||
expectedRole: role(rules("a"), nil, nil),
|
||||
actualRole: role(rules("b"), nil, nil),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: role(rules("a"), nil, nil),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"different rules with union": {
|
||||
expectedRole: role(rules("a"), nil, nil),
|
||||
actualRole: role(rules("b"), nil, nil),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: role(rules("b", "a"), nil, nil),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"match labels without union": {
|
||||
expectedRole: role(rules("a"), ss{"1": "a"}, nil),
|
||||
actualRole: role(rules("a"), ss{"1": "a"}, nil),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: nil,
|
||||
expectedReconciliationNeeded: false,
|
||||
},
|
||||
"match labels with union": {
|
||||
expectedRole: role(rules("a"), ss{"1": "a"}, nil),
|
||||
actualRole: role(rules("a"), ss{"1": "a"}, nil),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: nil,
|
||||
expectedReconciliationNeeded: false,
|
||||
},
|
||||
"different labels without union": {
|
||||
expectedRole: role(rules("a"), ss{"1": "a"}, nil),
|
||||
actualRole: role(rules("a"), ss{"2": "b"}, nil),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: role(rules("a"), ss{"1": "a", "2": "b"}, nil),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"different labels with union": {
|
||||
expectedRole: role(rules("a"), ss{"1": "a"}, nil),
|
||||
actualRole: role(rules("a"), ss{"2": "b"}, nil),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: role(rules("a"), ss{"1": "a", "2": "b"}, nil),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"different labels and rules without union": {
|
||||
expectedRole: role(rules("a"), ss{"1": "a"}, nil),
|
||||
actualRole: role(rules("b"), ss{"2": "b"}, nil),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: role(rules("a"), ss{"1": "a", "2": "b"}, nil),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"different labels and rules with union": {
|
||||
expectedRole: role(rules("a"), ss{"1": "a"}, nil),
|
||||
actualRole: role(rules("b"), ss{"2": "b"}, nil),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: role(rules("b", "a"), ss{"1": "a", "2": "b"}, nil),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"conflicting labels and rules without union": {
|
||||
expectedRole: role(rules("a"), ss{"1": "a"}, nil),
|
||||
actualRole: role(rules("b"), ss{"1": "b"}, nil),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: role(rules("a"), ss{"1": "b"}, nil),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"conflicting labels and rules with union": {
|
||||
expectedRole: role(rules("a"), ss{"1": "a"}, nil),
|
||||
actualRole: role(rules("b"), ss{"1": "b"}, nil),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: role(rules("b", "a"), ss{"1": "b"}, nil),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"match annotations without union": {
|
||||
expectedRole: role(rules("a"), nil, ss{"1": "a"}),
|
||||
actualRole: role(rules("a"), nil, ss{"1": "a"}),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: nil,
|
||||
expectedReconciliationNeeded: false,
|
||||
},
|
||||
"match annotations with union": {
|
||||
expectedRole: role(rules("a"), nil, ss{"1": "a"}),
|
||||
actualRole: role(rules("a"), nil, ss{"1": "a"}),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: nil,
|
||||
expectedReconciliationNeeded: false,
|
||||
},
|
||||
"different annotations without union": {
|
||||
expectedRole: role(rules("a"), nil, ss{"1": "a"}),
|
||||
actualRole: role(rules("a"), nil, ss{"2": "b"}),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: role(rules("a"), nil, ss{"1": "a", "2": "b"}),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"different annotations with union": {
|
||||
expectedRole: role(rules("a"), nil, ss{"1": "a"}),
|
||||
actualRole: role(rules("a"), nil, ss{"2": "b"}),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: role(rules("a"), nil, ss{"1": "a", "2": "b"}),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"different annotations and rules without union": {
|
||||
expectedRole: role(rules("a"), nil, ss{"1": "a"}),
|
||||
actualRole: role(rules("b"), nil, ss{"2": "b"}),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: role(rules("a"), nil, ss{"1": "a", "2": "b"}),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"different annotations and rules with union": {
|
||||
expectedRole: role(rules("a"), nil, ss{"1": "a"}),
|
||||
actualRole: role(rules("b"), nil, ss{"2": "b"}),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: role(rules("b", "a"), nil, ss{"1": "a", "2": "b"}),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"conflicting annotations and rules without union": {
|
||||
expectedRole: role(rules("a"), nil, ss{"1": "a"}),
|
||||
actualRole: role(rules("b"), nil, ss{"1": "b"}),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: role(rules("a"), nil, ss{"1": "b"}),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"conflicting annotations and rules with union": {
|
||||
expectedRole: role(rules("a"), nil, ss{"1": "a"}),
|
||||
actualRole: role(rules("b"), nil, ss{"1": "b"}),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: role(rules("b", "a"), nil, ss{"1": "b"}),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"conflicting labels/annotations and rules without union": {
|
||||
expectedRole: role(rules("a"), ss{"3": "d"}, ss{"1": "a"}),
|
||||
actualRole: role(rules("b"), ss{"4": "e"}, ss{"1": "b"}),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: role(rules("a"), ss{"3": "d", "4": "e"}, ss{"1": "b"}),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"conflicting labels/annotations and rules with union": {
|
||||
expectedRole: role(rules("a"), ss{"3": "d"}, ss{"1": "a"}),
|
||||
actualRole: role(rules("b"), ss{"4": "e"}, ss{"1": "b"}),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: role(rules("b", "a"), ss{"3": "d", "4": "e"}, ss{"1": "b"}),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"complex labels/annotations and rules without union": {
|
||||
expectedRole: role(rules("pods", "nodes", "secrets"), ss{"env": "prod", "color": "blue"}, ss{"description": "fancy", "system": "true"}),
|
||||
actualRole: role(rules("nodes", "images", "projects"), ss{"color": "red", "team": "pm"}, ss{"system": "false", "owner": "admin", "vip": "yes"}),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: role(
|
||||
rules("pods", "nodes", "secrets"),
|
||||
ss{"env": "prod", "color": "red", "team": "pm"},
|
||||
ss{"description": "fancy", "system": "false", "owner": "admin", "vip": "yes"}),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"complex labels/annotations and rules with union": {
|
||||
expectedRole: role(rules("pods", "nodes", "secrets"), ss{"env": "prod", "color": "blue", "manager": "randy"}, ss{"description": "fancy", "system": "true", "up": "true"}),
|
||||
actualRole: role(rules("nodes", "images", "projects"), ss{"color": "red", "team": "pm"}, ss{"system": "false", "owner": "admin", "vip": "yes", "rate": "down"}),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: role(
|
||||
rules("nodes", "images", "projects", "pods", "secrets"),
|
||||
ss{"env": "prod", "manager": "randy", "color": "red", "team": "pm"},
|
||||
ss{"description": "fancy", "system": "false", "owner": "admin", "vip": "yes", "rate": "down", "up": "true"}),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range tests {
|
||||
actualRole := ClusterRoleRuleOwner{ClusterRole: tc.actualRole}
|
||||
expectedRole := ClusterRoleRuleOwner{ClusterRole: tc.expectedRole}
|
||||
result, err := computeReconciledRole(actualRole, expectedRole, tc.removeExtraPermissions)
|
||||
if err != nil {
|
||||
t.Errorf("%s: %v", k, err)
|
||||
continue
|
||||
}
|
||||
reconciliationNeeded := result.Operation != ReconcileNone
|
||||
if reconciliationNeeded != tc.expectedReconciliationNeeded {
|
||||
t.Errorf("%s: Expected\n\t%v\ngot\n\t%v", k, tc.expectedReconciliationNeeded, reconciliationNeeded)
|
||||
continue
|
||||
}
|
||||
if reconciliationNeeded && !helper.Semantic.DeepEqual(result.Role.(ClusterRoleRuleOwner).ClusterRole, tc.expectedReconciledRole) {
|
||||
t.Errorf("%s: Expected\n\t%#v\ngot\n\t%#v", k, tc.expectedReconciledRole, result.Role)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func aggregatedRole(aggregationRule *rbac.AggregationRule) *rbac.ClusterRole {
|
||||
return &rbac.ClusterRole{
|
||||
AggregationRule: aggregationRule,
|
||||
}
|
||||
}
|
||||
|
||||
func aggregationrule(selectors []map[string]string) *rbac.AggregationRule {
|
||||
ret := &rbac.AggregationRule{}
|
||||
for _, selector := range selectors {
|
||||
ret.ClusterRoleSelectors = append(ret.ClusterRoleSelectors,
|
||||
metav1.LabelSelector{MatchLabels: selector})
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func TestComputeReconciledRoleAggregationRules(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
expectedRole *rbac.ClusterRole
|
||||
actualRole *rbac.ClusterRole
|
||||
removeExtraPermissions bool
|
||||
|
||||
expectedReconciledRole *rbac.ClusterRole
|
||||
expectedReconciliationNeeded bool
|
||||
}{
|
||||
"empty": {
|
||||
expectedRole: aggregatedRole(&rbac.AggregationRule{}),
|
||||
actualRole: aggregatedRole(nil),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: nil,
|
||||
expectedReconciliationNeeded: false,
|
||||
},
|
||||
"empty-2": {
|
||||
expectedRole: aggregatedRole(&rbac.AggregationRule{}),
|
||||
actualRole: aggregatedRole(&rbac.AggregationRule{}),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: nil,
|
||||
expectedReconciliationNeeded: false,
|
||||
},
|
||||
"match without union": {
|
||||
expectedRole: aggregatedRole(aggregationrule([]map[string]string{{"foo": "bar"}})),
|
||||
actualRole: aggregatedRole(aggregationrule([]map[string]string{{"foo": "bar"}})),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: nil,
|
||||
expectedReconciliationNeeded: false,
|
||||
},
|
||||
"match with union": {
|
||||
expectedRole: aggregatedRole(aggregationrule([]map[string]string{{"foo": "bar"}})),
|
||||
actualRole: aggregatedRole(aggregationrule([]map[string]string{{"foo": "bar"}})),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: nil,
|
||||
expectedReconciliationNeeded: false,
|
||||
},
|
||||
"different rules without union": {
|
||||
expectedRole: aggregatedRole(aggregationrule([]map[string]string{{"foo": "bar"}})),
|
||||
actualRole: aggregatedRole(aggregationrule([]map[string]string{{"alpha": "bravo"}})),
|
||||
removeExtraPermissions: true,
|
||||
|
||||
expectedReconciledRole: aggregatedRole(aggregationrule([]map[string]string{{"foo": "bar"}})),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
"different rules with union": {
|
||||
expectedRole: aggregatedRole(aggregationrule([]map[string]string{{"foo": "bar"}})),
|
||||
actualRole: aggregatedRole(aggregationrule([]map[string]string{{"alpha": "bravo"}})),
|
||||
removeExtraPermissions: false,
|
||||
|
||||
expectedReconciledRole: aggregatedRole(aggregationrule([]map[string]string{{"alpha": "bravo"}, {"foo": "bar"}})),
|
||||
expectedReconciliationNeeded: true,
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range tests {
|
||||
actualRole := ClusterRoleRuleOwner{ClusterRole: tc.actualRole}
|
||||
expectedRole := ClusterRoleRuleOwner{ClusterRole: tc.expectedRole}
|
||||
result, err := computeReconciledRole(actualRole, expectedRole, tc.removeExtraPermissions)
|
||||
if err != nil {
|
||||
t.Errorf("%s: %v", k, err)
|
||||
continue
|
||||
}
|
||||
reconciliationNeeded := result.Operation != ReconcileNone
|
||||
if reconciliationNeeded != tc.expectedReconciliationNeeded {
|
||||
t.Errorf("%s: Expected\n\t%v\ngot\n\t%v", k, tc.expectedReconciliationNeeded, reconciliationNeeded)
|
||||
continue
|
||||
}
|
||||
if reconciliationNeeded && !helper.Semantic.DeepEqual(result.Role.(ClusterRoleRuleOwner).ClusterRole, tc.expectedReconciledRole) {
|
||||
t.Errorf("%s: %v", k, diff.ObjectDiff(tc.expectedReconciledRole, result.Role.(ClusterRoleRuleOwner).ClusterRole))
|
||||
}
|
||||
}
|
||||
}
|
248
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/reconcile_rolebindings.go
generated
vendored
Normal file
248
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/reconcile_rolebindings.go
generated
vendored
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
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 (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
)
|
||||
|
||||
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 {
|
||||
GetObject() runtime.Object
|
||||
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)
|
||||
DeepCopyRoleBinding() RoleBinding
|
||||
}
|
||||
|
||||
// ReconcileRoleBindingOptions holds options for running a role binding reconciliation
|
||||
type ReconcileRoleBindingOptions struct {
|
||||
// RoleBinding is the expected rolebinding that will be reconciled
|
||||
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 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 RoleBinding
|
||||
|
||||
// MissingSubjects contains expected subjects that were missing from the currently persisted rolebinding
|
||||
MissingSubjects []rbac.Subject
|
||||
// ExtraSubjects contains extra subjects the currently persisted rolebinding had
|
||||
ExtraSubjects []rbac.Subject
|
||||
|
||||
// Operation is the API operation required to reconcile.
|
||||
// If no reconciliation was needed, it is set to ReconcileNone.
|
||||
// If options.Confirm == false, the reconcile was in dry-run mode, so the operation was not performed.
|
||||
// If result.Protected == true, the rolebinding opted out of reconciliation, so the operation was not performed.
|
||||
// Otherwise, the operation was performed.
|
||||
Operation ReconcileOperation
|
||||
// Protected indicates an existing role prevented reconciliation
|
||||
Protected bool
|
||||
}
|
||||
|
||||
func (o *ReconcileRoleBindingOptions) Run() (*ReconcileClusterRoleBindingResult, error) {
|
||||
return o.run(0)
|
||||
}
|
||||
|
||||
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 {
|
||||
return nil, fmt.Errorf("exceeded maximum attempts")
|
||||
}
|
||||
|
||||
var result *ReconcileClusterRoleBindingResult
|
||||
|
||||
existingBinding, err := o.Client.Get(o.RoleBinding.GetNamespace(), o.RoleBinding.GetName())
|
||||
switch {
|
||||
case errors.IsNotFound(err):
|
||||
result = &ReconcileClusterRoleBindingResult{
|
||||
RoleBinding: o.RoleBinding,
|
||||
MissingSubjects: o.RoleBinding.GetSubjects(),
|
||||
Operation: ReconcileCreate,
|
||||
}
|
||||
|
||||
case err != nil:
|
||||
return nil, err
|
||||
|
||||
default:
|
||||
result, err = computeReconciledRoleBinding(existingBinding, o.RoleBinding, o.RemoveExtraSubjects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// If reconcile-protected, short-circuit
|
||||
if result.Protected {
|
||||
return result, nil
|
||||
}
|
||||
// If we're in dry-run mode, short-circuit
|
||||
if !o.Confirm {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
switch result.Operation {
|
||||
case ReconcileRecreate:
|
||||
// Try deleting
|
||||
err := o.Client.Delete(existingBinding.GetNamespace(), existingBinding.GetName(), existingBinding.GetUID())
|
||||
switch {
|
||||
case err == nil, errors.IsNotFound(err):
|
||||
// object no longer exists, as desired
|
||||
case errors.IsConflict(err):
|
||||
// delete failed because our UID precondition conflicted
|
||||
// this could mean another object exists with a different UID, re-run
|
||||
return o.run(attempts + 1)
|
||||
default:
|
||||
// return other errors
|
||||
return nil, err
|
||||
}
|
||||
// continue to create
|
||||
fallthrough
|
||||
case ReconcileCreate:
|
||||
created, err := o.Client.Create(result.RoleBinding)
|
||||
// If created since we started this reconcile, re-run
|
||||
if errors.IsAlreadyExists(err) {
|
||||
return o.run(attempts + 1)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.RoleBinding = created
|
||||
|
||||
case ReconcileUpdate:
|
||||
updated, err := o.Client.Update(result.RoleBinding)
|
||||
// If deleted since we started this reconcile, re-run
|
||||
if errors.IsNotFound(err) {
|
||||
return o.run(attempts + 1)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result.RoleBinding = updated
|
||||
|
||||
case ReconcileNone:
|
||||
// no-op
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid operation: %v", result.Operation)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 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 RoleBinding, removeExtraSubjects bool) (*ReconcileClusterRoleBindingResult, error) {
|
||||
result := &ReconcileClusterRoleBindingResult{Operation: ReconcileNone}
|
||||
|
||||
result.Protected = (existing.GetAnnotations()[rbac.AutoUpdateAnnotationKey] == "false")
|
||||
|
||||
// Reset the binding completely if the roleRef is different
|
||||
if expected.GetRoleRef() != existing.GetRoleRef() {
|
||||
result.RoleBinding = expected
|
||||
result.Operation = ReconcileRecreate
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// Start with a copy of the existing object
|
||||
result.RoleBinding = existing.DeepCopyRoleBinding()
|
||||
|
||||
// Merge expected annotations and labels
|
||||
result.RoleBinding.SetAnnotations(merge(expected.GetAnnotations(), result.RoleBinding.GetAnnotations()))
|
||||
if !reflect.DeepEqual(result.RoleBinding.GetAnnotations(), existing.GetAnnotations()) {
|
||||
result.Operation = ReconcileUpdate
|
||||
}
|
||||
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.GetSubjects(), existing.GetSubjects())
|
||||
|
||||
switch {
|
||||
case !removeExtraSubjects && len(result.MissingSubjects) > 0:
|
||||
// add missing subjects in the union case
|
||||
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.SetSubjects(expected.GetSubjects())
|
||||
result.Operation = ReconcileUpdate
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func contains(list []rbac.Subject, item rbac.Subject) bool {
|
||||
for _, listItem := range list {
|
||||
if listItem == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// diffSubjectLists returns lists containing the items unique to each provided list:
|
||||
// list1Only = list1 - list2
|
||||
// list2Only = list2 - list1
|
||||
// if both returned lists are empty, the provided lists are equal
|
||||
func diffSubjectLists(list1 []rbac.Subject, list2 []rbac.Subject) (list1Only []rbac.Subject, list2Only []rbac.Subject) {
|
||||
for _, list1Item := range list1 {
|
||||
if !contains(list2, list1Item) {
|
||||
if !contains(list1Only, list1Item) {
|
||||
list1Only = append(list1Only, list1Item)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, list2Item := range list2 {
|
||||
if !contains(list1, list2Item) {
|
||||
if !contains(list2Only, list2Item) {
|
||||
list2Only = append(list2Only, list2Item)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
181
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/reconcile_rolebindings_test.go
generated
vendored
Normal file
181
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/reconcile_rolebindings_test.go
generated
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
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 (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
)
|
||||
|
||||
func binding(roleRef rbac.RoleRef, subjects []rbac.Subject) *rbac.ClusterRoleBinding {
|
||||
return &rbac.ClusterRoleBinding{RoleRef: roleRef, Subjects: subjects}
|
||||
}
|
||||
|
||||
func ref(name string) rbac.RoleRef {
|
||||
return rbac.RoleRef{Name: name}
|
||||
}
|
||||
|
||||
func subject(name string) rbac.Subject {
|
||||
return rbac.Subject{Name: name}
|
||||
}
|
||||
|
||||
func subjects(names ...string) []rbac.Subject {
|
||||
r := []rbac.Subject{}
|
||||
for _, name := range names {
|
||||
r = append(r, subject(name))
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func TestDiffObjectReferenceLists(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
A []rbac.Subject
|
||||
B []rbac.Subject
|
||||
ExpectedOnlyA []rbac.Subject
|
||||
ExpectedOnlyB []rbac.Subject
|
||||
}{
|
||||
"empty": {},
|
||||
|
||||
"matching, order-independent": {
|
||||
A: subjects("foo", "bar"),
|
||||
B: subjects("bar", "foo"),
|
||||
},
|
||||
|
||||
"partial match": {
|
||||
A: subjects("foo", "bar"),
|
||||
B: subjects("foo", "baz"),
|
||||
ExpectedOnlyA: subjects("bar"),
|
||||
ExpectedOnlyB: subjects("baz"),
|
||||
},
|
||||
|
||||
"missing": {
|
||||
A: subjects("foo"),
|
||||
B: subjects("bar"),
|
||||
ExpectedOnlyA: subjects("foo"),
|
||||
ExpectedOnlyB: subjects("bar"),
|
||||
},
|
||||
|
||||
"remove duplicates": {
|
||||
A: subjects("foo", "foo"),
|
||||
B: subjects("bar", "bar"),
|
||||
ExpectedOnlyA: subjects("foo"),
|
||||
ExpectedOnlyB: subjects("bar"),
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range tests {
|
||||
onlyA, onlyB := diffSubjectLists(tc.A, tc.B)
|
||||
if !helper.Semantic.DeepEqual(onlyA, tc.ExpectedOnlyA) {
|
||||
t.Errorf("%s: Expected %#v, got %#v", k, tc.ExpectedOnlyA, onlyA)
|
||||
}
|
||||
if !helper.Semantic.DeepEqual(onlyB, tc.ExpectedOnlyB) {
|
||||
t.Errorf("%s: Expected %#v, got %#v", k, tc.ExpectedOnlyB, onlyB)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestComputeUpdate(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
ExpectedBinding *rbac.ClusterRoleBinding
|
||||
ActualBinding *rbac.ClusterRoleBinding
|
||||
RemoveExtraSubjects bool
|
||||
|
||||
ExpectedUpdatedBinding *rbac.ClusterRoleBinding
|
||||
ExpectedUpdateNeeded bool
|
||||
}{
|
||||
"match without union": {
|
||||
ExpectedBinding: binding(ref("role"), subjects("a")),
|
||||
ActualBinding: binding(ref("role"), subjects("a")),
|
||||
RemoveExtraSubjects: true,
|
||||
|
||||
ExpectedUpdatedBinding: nil,
|
||||
ExpectedUpdateNeeded: false,
|
||||
},
|
||||
"match with union": {
|
||||
ExpectedBinding: binding(ref("role"), subjects("a")),
|
||||
ActualBinding: binding(ref("role"), subjects("a")),
|
||||
RemoveExtraSubjects: false,
|
||||
|
||||
ExpectedUpdatedBinding: nil,
|
||||
ExpectedUpdateNeeded: false,
|
||||
},
|
||||
|
||||
"different roleref with identical subjects": {
|
||||
ExpectedBinding: binding(ref("role"), subjects("a")),
|
||||
ActualBinding: binding(ref("differentRole"), subjects("a")),
|
||||
RemoveExtraSubjects: false,
|
||||
|
||||
ExpectedUpdatedBinding: binding(ref("role"), subjects("a")),
|
||||
ExpectedUpdateNeeded: true,
|
||||
},
|
||||
|
||||
"extra subjects without union": {
|
||||
ExpectedBinding: binding(ref("role"), subjects("a")),
|
||||
ActualBinding: binding(ref("role"), subjects("a", "b")),
|
||||
RemoveExtraSubjects: true,
|
||||
|
||||
ExpectedUpdatedBinding: binding(ref("role"), subjects("a")),
|
||||
ExpectedUpdateNeeded: true,
|
||||
},
|
||||
"extra subjects with union": {
|
||||
ExpectedBinding: binding(ref("role"), subjects("a")),
|
||||
ActualBinding: binding(ref("role"), subjects("a", "b")),
|
||||
RemoveExtraSubjects: false,
|
||||
|
||||
ExpectedUpdatedBinding: nil,
|
||||
ExpectedUpdateNeeded: false,
|
||||
},
|
||||
|
||||
"missing subjects without union": {
|
||||
ExpectedBinding: binding(ref("role"), subjects("a", "c")),
|
||||
ActualBinding: binding(ref("role"), subjects("a", "b")),
|
||||
RemoveExtraSubjects: true,
|
||||
|
||||
ExpectedUpdatedBinding: binding(ref("role"), subjects("a", "c")),
|
||||
ExpectedUpdateNeeded: true,
|
||||
},
|
||||
"missing subjects with union": {
|
||||
ExpectedBinding: binding(ref("role"), subjects("a", "c")),
|
||||
ActualBinding: binding(ref("role"), subjects("a", "b")),
|
||||
RemoveExtraSubjects: false,
|
||||
|
||||
ExpectedUpdatedBinding: binding(ref("role"), subjects("a", "b", "c")),
|
||||
ExpectedUpdateNeeded: true,
|
||||
},
|
||||
}
|
||||
|
||||
for k, tc := range tests {
|
||||
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.(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
|
||||
}
|
||||
if updateNeeded && !helper.Semantic.DeepEqual(updatedBinding, tc.ExpectedUpdatedBinding) {
|
||||
t.Errorf("%s: Expected\n\t%v %v\ngot\n\t%v %v", k, tc.ExpectedUpdatedBinding.RoleRef, tc.ExpectedUpdatedBinding.Subjects, updatedBinding.RoleRef, updatedBinding.Subjects)
|
||||
}
|
||||
}
|
||||
}
|
112
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/role_interfaces.go
generated
vendored
Normal file
112
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/role_interfaces.go
generated
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
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 (
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
core "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/pkg/registry/rbac/reconciliation.RuleOwner
|
||||
// +k8s:deepcopy-gen:nonpointer-interfaces=true
|
||||
type RoleRuleOwner struct {
|
||||
Role *rbac.Role
|
||||
}
|
||||
|
||||
func (o RoleRuleOwner) GetObject() runtime.Object {
|
||||
return o.Role
|
||||
}
|
||||
|
||||
func (o RoleRuleOwner) GetNamespace() string {
|
||||
return o.Role.Namespace
|
||||
}
|
||||
|
||||
func (o RoleRuleOwner) GetName() string {
|
||||
return o.Role.Name
|
||||
}
|
||||
|
||||
func (o RoleRuleOwner) GetLabels() map[string]string {
|
||||
return o.Role.Labels
|
||||
}
|
||||
|
||||
func (o RoleRuleOwner) SetLabels(in map[string]string) {
|
||||
o.Role.Labels = in
|
||||
}
|
||||
|
||||
func (o RoleRuleOwner) GetAnnotations() map[string]string {
|
||||
return o.Role.Annotations
|
||||
}
|
||||
|
||||
func (o RoleRuleOwner) SetAnnotations(in map[string]string) {
|
||||
o.Role.Annotations = in
|
||||
}
|
||||
|
||||
func (o RoleRuleOwner) GetRules() []rbac.PolicyRule {
|
||||
return o.Role.Rules
|
||||
}
|
||||
|
||||
func (o RoleRuleOwner) SetRules(in []rbac.PolicyRule) {
|
||||
o.Role.Rules = in
|
||||
}
|
||||
|
||||
func (o RoleRuleOwner) GetAggregationRule() *rbac.AggregationRule {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o RoleRuleOwner) SetAggregationRule(in *rbac.AggregationRule) {
|
||||
}
|
||||
|
||||
type RoleModifier struct {
|
||||
Client internalversion.RolesGetter
|
||||
NamespaceClient core.NamespaceInterface
|
||||
}
|
||||
|
||||
func (c RoleModifier) Get(namespace, name string) (RuleOwner, error) {
|
||||
ret, err := c.Client.Roles(namespace).Get(name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return RoleRuleOwner{Role: ret}, err
|
||||
}
|
||||
|
||||
func (c RoleModifier) Create(in RuleOwner) (RuleOwner, error) {
|
||||
ns := &api.Namespace{ObjectMeta: metav1.ObjectMeta{Name: in.GetNamespace()}}
|
||||
if _, err := c.NamespaceClient.Create(ns); err != nil && !apierrors.IsAlreadyExists(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret, err := c.Client.Roles(in.GetNamespace()).Create(in.(RoleRuleOwner).Role)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return RoleRuleOwner{Role: ret}, err
|
||||
}
|
||||
|
||||
func (c RoleModifier) Update(in RuleOwner) (RuleOwner, error) {
|
||||
ret, err := c.Client.Roles(in.GetNamespace()).Update(in.(RoleRuleOwner).Role)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return RoleRuleOwner{Role: ret}, err
|
||||
|
||||
}
|
118
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/rolebinding_interfaces.go
generated
vendored
Normal file
118
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/rolebinding_interfaces.go
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
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 (
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
core "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/pkg/registry/rbac/reconciliation.RoleBinding
|
||||
// +k8s:deepcopy-gen:nonpointer-interfaces=true
|
||||
type RoleBindingAdapter struct {
|
||||
RoleBinding *rbac.RoleBinding
|
||||
}
|
||||
|
||||
func (o RoleBindingAdapter) GetObject() runtime.Object {
|
||||
return o.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
|
||||
NamespaceClient core.NamespaceInterface
|
||||
}
|
||||
|
||||
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) {
|
||||
ns := &api.Namespace{ObjectMeta: metav1.ObjectMeta{Name: in.GetNamespace()}}
|
||||
if _, err := c.NamespaceClient.Create(ns); err != nil && !apierrors.IsAlreadyExists(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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}})
|
||||
}
|
145
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/zz_generated.deepcopy.go
generated
vendored
Normal file
145
vendor/k8s.io/kubernetes/pkg/registry/rbac/reconciliation/zz_generated.deepcopy.go
generated
vendored
Normal file
@ -0,0 +1,145 @@
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2018 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.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
|
||||
package reconciliation
|
||||
|
||||
import (
|
||||
rbac "k8s.io/kubernetes/pkg/apis/rbac"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterRoleBindingAdapter) DeepCopyInto(out *ClusterRoleBindingAdapter) {
|
||||
*out = *in
|
||||
if in.ClusterRoleBinding != nil {
|
||||
in, out := &in.ClusterRoleBinding, &out.ClusterRoleBinding
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(rbac.ClusterRoleBinding)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRoleBindingAdapter.
|
||||
func (in *ClusterRoleBindingAdapter) DeepCopy() *ClusterRoleBindingAdapter {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterRoleBindingAdapter)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyRoleBinding is an autogenerated deepcopy function, copying the receiver, creating a new RoleBinding.
|
||||
func (in ClusterRoleBindingAdapter) DeepCopyRoleBinding() RoleBinding {
|
||||
return *in.DeepCopy()
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterRoleRuleOwner) DeepCopyInto(out *ClusterRoleRuleOwner) {
|
||||
*out = *in
|
||||
if in.ClusterRole != nil {
|
||||
in, out := &in.ClusterRole, &out.ClusterRole
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(rbac.ClusterRole)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRoleRuleOwner.
|
||||
func (in *ClusterRoleRuleOwner) DeepCopy() *ClusterRoleRuleOwner {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterRoleRuleOwner)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyRuleOwner is an autogenerated deepcopy function, copying the receiver, creating a new RuleOwner.
|
||||
func (in ClusterRoleRuleOwner) DeepCopyRuleOwner() RuleOwner {
|
||||
return *in.DeepCopy()
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RoleBindingAdapter) DeepCopyInto(out *RoleBindingAdapter) {
|
||||
*out = *in
|
||||
if in.RoleBinding != nil {
|
||||
in, out := &in.RoleBinding, &out.RoleBinding
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(rbac.RoleBinding)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleBindingAdapter.
|
||||
func (in *RoleBindingAdapter) DeepCopy() *RoleBindingAdapter {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RoleBindingAdapter)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyRoleBinding is an autogenerated deepcopy function, copying the receiver, creating a new RoleBinding.
|
||||
func (in RoleBindingAdapter) DeepCopyRoleBinding() RoleBinding {
|
||||
return *in.DeepCopy()
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RoleRuleOwner) DeepCopyInto(out *RoleRuleOwner) {
|
||||
*out = *in
|
||||
if in.Role != nil {
|
||||
in, out := &in.Role, &out.Role
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(rbac.Role)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleRuleOwner.
|
||||
func (in *RoleRuleOwner) DeepCopy() *RoleRuleOwner {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RoleRuleOwner)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyRuleOwner is an autogenerated deepcopy function, copying the receiver, creating a new RuleOwner.
|
||||
func (in RoleRuleOwner) DeepCopyRuleOwner() RuleOwner {
|
||||
return *in.DeepCopy()
|
||||
}
|
Reference in New Issue
Block a user