mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 15:05:27 +00:00
handle clusterrole migration
This commit is contained in:
parent
e52383c486
commit
f34fb9b0ab
@ -42,7 +42,10 @@ func NewStorage(s rest.StandardStorage, ruleResolver rbacregistryvalidation.Auth
|
|||||||
return &Storage{s, ruleResolver}
|
return &Storage{s, ruleResolver}
|
||||||
}
|
}
|
||||||
|
|
||||||
var fullAuthority = []rbac.PolicyRule{rbac.NewRule("*").Groups("*").Resources("*").RuleOrDie()}
|
var fullAuthority = []rbac.PolicyRule{
|
||||||
|
rbac.NewRule("*").Groups("*").Resources("*").RuleOrDie(),
|
||||||
|
rbac.NewRule("*").URLs("*").RuleOrDie(),
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object, createValidatingAdmission rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) {
|
func (s *Storage) Create(ctx genericapirequest.Context, obj runtime.Object, createValidatingAdmission rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) {
|
||||||
if rbacregistry.EscalationAllowed(ctx) {
|
if rbacregistry.EscalationAllowed(ctx) {
|
||||||
|
@ -18,6 +18,7 @@ go_test(
|
|||||||
"//pkg/apis/core/helper:go_default_library",
|
"//pkg/apis/core/helper:go_default_library",
|
||||||
"//pkg/apis/rbac: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/apis/meta/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -66,6 +66,14 @@ func (o ClusterRoleRuleOwner) SetRules(in []rbac.PolicyRule) {
|
|||||||
o.ClusterRole.Rules = in
|
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 {
|
type ClusterRoleModifier struct {
|
||||||
Client internalversion.ClusterRoleInterface
|
Client internalversion.ClusterRoleInterface
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/api/equality"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||||
"k8s.io/kubernetes/pkg/registry/rbac/validation"
|
"k8s.io/kubernetes/pkg/registry/rbac/validation"
|
||||||
@ -51,6 +53,8 @@ type RuleOwner interface {
|
|||||||
SetAnnotations(map[string]string)
|
SetAnnotations(map[string]string)
|
||||||
GetRules() []rbac.PolicyRule
|
GetRules() []rbac.PolicyRule
|
||||||
SetRules([]rbac.PolicyRule)
|
SetRules([]rbac.PolicyRule)
|
||||||
|
GetAggregationRule() *rbac.AggregationRule
|
||||||
|
SetAggregationRule(*rbac.AggregationRule)
|
||||||
DeepCopyRuleOwner() RuleOwner
|
DeepCopyRuleOwner() RuleOwner
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +79,11 @@ type ReconcileClusterRoleResult struct {
|
|||||||
// ExtraRules contains extra permissions the currently persisted role had
|
// ExtraRules contains extra permissions the currently persisted role had
|
||||||
ExtraRules []rbac.PolicyRule
|
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.
|
// Operation is the API operation required to reconcile.
|
||||||
// If no reconciliation was needed, it is set to ReconcileNone.
|
// 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 options.Confirm == false, the reconcile was in dry-run mode, so the operation was not performed.
|
||||||
@ -101,10 +110,15 @@ func (o *ReconcileRoleOptions) run(attempts int) (*ReconcileClusterRoleResult, e
|
|||||||
existing, err := o.Client.Get(o.Role.GetNamespace(), o.Role.GetName())
|
existing, err := o.Client.Get(o.Role.GetNamespace(), o.Role.GetName())
|
||||||
switch {
|
switch {
|
||||||
case errors.IsNotFound(err):
|
case errors.IsNotFound(err):
|
||||||
|
aggregationRule := o.Role.GetAggregationRule()
|
||||||
|
if aggregationRule == nil {
|
||||||
|
aggregationRule = &rbac.AggregationRule{}
|
||||||
|
}
|
||||||
result = &ReconcileClusterRoleResult{
|
result = &ReconcileClusterRoleResult{
|
||||||
Role: o.Role,
|
Role: o.Role,
|
||||||
MissingRules: o.Role.GetRules(),
|
MissingRules: o.Role.GetRules(),
|
||||||
Operation: ReconcileCreate,
|
MissingAggregationRuleSelectors: aggregationRule.ClusterRoleSelectors,
|
||||||
|
Operation: ReconcileCreate,
|
||||||
}
|
}
|
||||||
|
|
||||||
case err != nil:
|
case err != nil:
|
||||||
@ -195,6 +209,26 @@ func computeReconciledRole(existing, expected RuleOwner, removeExtraPermissions
|
|||||||
result.Operation = ReconcileUpdate
|
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
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,3 +245,37 @@ func merge(maps ...map[string]string) map[string]string {
|
|||||||
}
|
}
|
||||||
return output
|
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
|
||||||
|
}
|
||||||
|
@ -20,12 +20,16 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
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/core/helper"
|
||||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||||
)
|
)
|
||||||
|
|
||||||
func role(rules []rbac.PolicyRule, labels map[string]string, annotations map[string]string) *rbac.ClusterRole {
|
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}}
|
return &rbac.ClusterRole{
|
||||||
|
Rules: rules,
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Labels: labels, Annotations: annotations},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func rules(resources ...string) []rbac.PolicyRule {
|
func rules(resources ...string) []rbac.PolicyRule {
|
||||||
@ -38,7 +42,7 @@ func rules(resources ...string) []rbac.PolicyRule {
|
|||||||
|
|
||||||
type ss map[string]string
|
type ss map[string]string
|
||||||
|
|
||||||
func TestComputeReconciledRole(t *testing.T) {
|
func TestComputeReconciledRoleRules(t *testing.T) {
|
||||||
tests := map[string]struct {
|
tests := map[string]struct {
|
||||||
expectedRole *rbac.ClusterRole
|
expectedRole *rbac.ClusterRole
|
||||||
actualRole *rbac.ClusterRole
|
actualRole *rbac.ClusterRole
|
||||||
@ -273,3 +277,96 @@ func TestComputeReconciledRole(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -69,6 +69,13 @@ func (o RoleRuleOwner) SetRules(in []rbac.PolicyRule) {
|
|||||||
o.Role.Rules = in
|
o.Role.Rules = in
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (o RoleRuleOwner) GetAggregationRule() *rbac.AggregationRule {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o RoleRuleOwner) SetAggregationRule(in *rbac.AggregationRule) {
|
||||||
|
}
|
||||||
|
|
||||||
type RoleModifier struct {
|
type RoleModifier struct {
|
||||||
Client internalversion.RolesGetter
|
Client internalversion.RolesGetter
|
||||||
NamespaceClient core.NamespaceInterface
|
NamespaceClient core.NamespaceInterface
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
rbacapiv1 "k8s.io/api/rbac/v1"
|
rbacapiv1 "k8s.io/api/rbac/v1"
|
||||||
rbacapiv1alpha1 "k8s.io/api/rbac/v1alpha1"
|
rbacapiv1alpha1 "k8s.io/api/rbac/v1alpha1"
|
||||||
rbacapiv1beta1 "k8s.io/api/rbac/v1beta1"
|
rbacapiv1beta1 "k8s.io/api/rbac/v1beta1"
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
@ -134,10 +135,11 @@ func (p RESTStorageProvider) storage(version schema.GroupVersion, apiResourceCon
|
|||||||
|
|
||||||
func (p RESTStorageProvider) PostStartHook() (string, genericapiserver.PostStartHookFunc, error) {
|
func (p RESTStorageProvider) PostStartHook() (string, genericapiserver.PostStartHookFunc, error) {
|
||||||
policy := &PolicyData{
|
policy := &PolicyData{
|
||||||
ClusterRoles: append(bootstrappolicy.ClusterRoles(), bootstrappolicy.ControllerRoles()...),
|
ClusterRoles: append(bootstrappolicy.ClusterRoles(), bootstrappolicy.ControllerRoles()...),
|
||||||
ClusterRoleBindings: append(bootstrappolicy.ClusterRoleBindings(), bootstrappolicy.ControllerRoleBindings()...),
|
ClusterRoleBindings: append(bootstrappolicy.ClusterRoleBindings(), bootstrappolicy.ControllerRoleBindings()...),
|
||||||
Roles: bootstrappolicy.NamespaceRoles(),
|
Roles: bootstrappolicy.NamespaceRoles(),
|
||||||
RoleBindings: bootstrappolicy.NamespaceRoleBindings(),
|
RoleBindings: bootstrappolicy.NamespaceRoleBindings(),
|
||||||
|
ClusterRolesToAggregate: bootstrappolicy.ClusterRolesToAggregate(),
|
||||||
}
|
}
|
||||||
return PostStartHookName, policy.EnsureRBACPolicy(), nil
|
return PostStartHookName, policy.EnsureRBACPolicy(), nil
|
||||||
}
|
}
|
||||||
@ -147,6 +149,8 @@ type PolicyData struct {
|
|||||||
ClusterRoleBindings []rbac.ClusterRoleBinding
|
ClusterRoleBindings []rbac.ClusterRoleBinding
|
||||||
Roles map[string][]rbac.Role
|
Roles map[string][]rbac.Role
|
||||||
RoleBindings map[string][]rbac.RoleBinding
|
RoleBindings map[string][]rbac.RoleBinding
|
||||||
|
// ClusterRolesToAggregate maps from previous clusterrole name to the new clusterrole name
|
||||||
|
ClusterRolesToAggregate map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PolicyData) EnsureRBACPolicy() genericapiserver.PostStartHookFunc {
|
func (p *PolicyData) EnsureRBACPolicy() genericapiserver.PostStartHookFunc {
|
||||||
@ -176,6 +180,13 @@ func (p *PolicyData) EnsureRBACPolicy() genericapiserver.PostStartHookFunc {
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the new cluster roles to aggregate do not yet exist, then we need to copy the old roles if they don't exist
|
||||||
|
// in new locations
|
||||||
|
if err := primeAggregatedClusterRoles(p.ClusterRolesToAggregate, clientset); err != nil {
|
||||||
|
utilruntime.HandleError(fmt.Errorf("unable to prime aggregated clusterroles: %v", err))
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ensure bootstrap roles are created or reconciled
|
// ensure bootstrap roles are created or reconciled
|
||||||
for _, clusterRole := range p.ClusterRoles {
|
for _, clusterRole := range p.ClusterRoles {
|
||||||
opts := reconciliation.ReconcileRoleOptions{
|
opts := reconciliation.ReconcileRoleOptions{
|
||||||
@ -310,3 +321,32 @@ func (p *PolicyData) EnsureRBACPolicy() genericapiserver.PostStartHookFunc {
|
|||||||
func (p RESTStorageProvider) GroupName() string {
|
func (p RESTStorageProvider) GroupName() string {
|
||||||
return rbac.GroupName
|
return rbac.GroupName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// primeAggregatedClusterRoles copies roles that have transitioned to aggregated roles and may need to pick up changes
|
||||||
|
// that were done to the legacy roles.
|
||||||
|
func primeAggregatedClusterRoles(clusterRolesToAggregate map[string]string, clusterRoleClient rbacclient.ClusterRolesGetter) error {
|
||||||
|
for oldName, newName := range clusterRolesToAggregate {
|
||||||
|
_, err := clusterRoleClient.ClusterRoles().Get(newName, metav1.GetOptions{})
|
||||||
|
if err == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !apierrors.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
existingRole, err := clusterRoleClient.ClusterRoles().Get(oldName, metav1.GetOptions{})
|
||||||
|
if apierrors.IsNotFound(err) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
glog.V(1).Infof("migrating %v to %v", existingRole.Name, newName)
|
||||||
|
existingRole.Name = newName
|
||||||
|
if _, err := clusterRoleClient.ClusterRoles().Create(existingRole); err != nil && !apierrors.IsAlreadyExists(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -68,6 +68,14 @@ func buildControllerRoles() ([]rbac.ClusterRole, []rbac.ClusterRoleBinding) {
|
|||||||
eventsRule(),
|
eventsRule(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "clusterrole-aggregation-controller"},
|
||||||
|
Rules: []rbac.PolicyRule{
|
||||||
|
// this controller must have full permissions to allow it to mutate any role in any way
|
||||||
|
rbac.NewRule("*").Groups("*").Resources("*").RuleOrDie(),
|
||||||
|
rbac.NewRule("*").URLs("*").RuleOrDie(),
|
||||||
|
},
|
||||||
|
})
|
||||||
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
|
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "cronjob-controller"},
|
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "cronjob-controller"},
|
||||||
Rules: []rbac.PolicyRule{
|
Rules: []rbac.PolicyRule{
|
||||||
|
@ -32,6 +32,7 @@ var rolesWithAllowStar = sets.NewString(
|
|||||||
saRolePrefix+"generic-garbage-collector",
|
saRolePrefix+"generic-garbage-collector",
|
||||||
saRolePrefix+"resourcequota-controller",
|
saRolePrefix+"resourcequota-controller",
|
||||||
saRolePrefix+"horizontal-pod-autoscaler",
|
saRolePrefix+"horizontal-pod-autoscaler",
|
||||||
|
saRolePrefix+"clusterrole-aggregation-controller",
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestNoStarsForControllers confirms that no controller role has star verbs, groups,
|
// TestNoStarsForControllers confirms that no controller role has star verbs, groups,
|
||||||
|
@ -176,6 +176,30 @@ func ClusterRoles() []rbac.ClusterRole {
|
|||||||
{
|
{
|
||||||
// a role for a namespace level admin. It is `edit` plus the power to grant permissions to other users.
|
// a role for a namespace level admin. It is `edit` plus the power to grant permissions to other users.
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "admin"},
|
ObjectMeta: metav1.ObjectMeta{Name: "admin"},
|
||||||
|
AggregationRule: &rbac.AggregationRule{
|
||||||
|
ClusterRoleSelectors: []metav1.LabelSelector{{MatchLabels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-admin": "true"}}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// a role for a namespace level editor. It grants access to all user level actions in a namespace.
|
||||||
|
// It does not grant powers for "privileged" resources which are domain of the system: `/status`
|
||||||
|
// subresources or `quota`/`limits` which are used to control namespaces
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "edit"},
|
||||||
|
AggregationRule: &rbac.AggregationRule{
|
||||||
|
ClusterRoleSelectors: []metav1.LabelSelector{{MatchLabels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-edit": "true"}}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// a role for namespace level viewing. It grants Read-only access to non-escalating resources in
|
||||||
|
// a namespace.
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "view"},
|
||||||
|
AggregationRule: &rbac.AggregationRule{
|
||||||
|
ClusterRoleSelectors: []metav1.LabelSelector{{MatchLabels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-view": "true"}}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// a role for a namespace level admin. It is `edit` plus the power to grant permissions to other users.
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "system:aggregate-to-admin", Labels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-admin": "true"}},
|
||||||
Rules: []rbac.PolicyRule{
|
Rules: []rbac.PolicyRule{
|
||||||
rbac.NewRule(ReadWrite...).Groups(legacyGroup).Resources("pods", "pods/attach", "pods/proxy", "pods/exec", "pods/portforward").RuleOrDie(),
|
rbac.NewRule(ReadWrite...).Groups(legacyGroup).Resources("pods", "pods/attach", "pods/proxy", "pods/exec", "pods/portforward").RuleOrDie(),
|
||||||
rbac.NewRule(ReadWrite...).Groups(legacyGroup).Resources("replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
|
rbac.NewRule(ReadWrite...).Groups(legacyGroup).Resources("replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
|
||||||
@ -211,7 +235,7 @@ func ClusterRoles() []rbac.ClusterRole {
|
|||||||
// a role for a namespace level editor. It grants access to all user level actions in a namespace.
|
// a role for a namespace level editor. It grants access to all user level actions in a namespace.
|
||||||
// It does not grant powers for "privileged" resources which are domain of the system: `/status`
|
// It does not grant powers for "privileged" resources which are domain of the system: `/status`
|
||||||
// subresources or `quota`/`limits` which are used to control namespaces
|
// subresources or `quota`/`limits` which are used to control namespaces
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "edit"},
|
ObjectMeta: metav1.ObjectMeta{Name: "system:aggregate-to-edit", Labels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-edit": "true"}},
|
||||||
Rules: []rbac.PolicyRule{
|
Rules: []rbac.PolicyRule{
|
||||||
rbac.NewRule(ReadWrite...).Groups(legacyGroup).Resources("pods", "pods/attach", "pods/proxy", "pods/exec", "pods/portforward").RuleOrDie(),
|
rbac.NewRule(ReadWrite...).Groups(legacyGroup).Resources("pods", "pods/attach", "pods/proxy", "pods/exec", "pods/portforward").RuleOrDie(),
|
||||||
rbac.NewRule(ReadWrite...).Groups(legacyGroup).Resources("replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
|
rbac.NewRule(ReadWrite...).Groups(legacyGroup).Resources("replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
|
||||||
@ -242,7 +266,7 @@ func ClusterRoles() []rbac.ClusterRole {
|
|||||||
{
|
{
|
||||||
// a role for namespace level viewing. It grants Read-only access to non-escalating resources in
|
// a role for namespace level viewing. It grants Read-only access to non-escalating resources in
|
||||||
// a namespace.
|
// a namespace.
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "view"},
|
ObjectMeta: metav1.ObjectMeta{Name: "system:aggregate-to-view", Labels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-view": "true"}},
|
||||||
Rules: []rbac.PolicyRule{
|
Rules: []rbac.PolicyRule{
|
||||||
rbac.NewRule(Read...).Groups(legacyGroup).Resources("pods", "replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
|
rbac.NewRule(Read...).Groups(legacyGroup).Resources("pods", "replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
|
||||||
"services", "endpoints", "persistentvolumeclaims", "configmaps").RuleOrDie(),
|
"services", "endpoints", "persistentvolumeclaims", "configmaps").RuleOrDie(),
|
||||||
@ -444,3 +468,11 @@ func ClusterRoleBindings() []rbac.ClusterRoleBinding {
|
|||||||
|
|
||||||
return rolebindings
|
return rolebindings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ClusterRolesToAggregate() map[string]string {
|
||||||
|
return map[string]string{
|
||||||
|
"admin": "system:aggregate-to-admin",
|
||||||
|
"edit": "system:aggregate-to-edit",
|
||||||
|
"view": "system:aggregate-to-view",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -53,11 +53,11 @@ func getSemanticRoles(roles []rbac.ClusterRole) semanticRoles {
|
|||||||
for i := range roles {
|
for i := range roles {
|
||||||
role := roles[i]
|
role := roles[i]
|
||||||
switch role.Name {
|
switch role.Name {
|
||||||
case "admin":
|
case "system:aggregate-to-admin":
|
||||||
ret.admin = &role
|
ret.admin = &role
|
||||||
case "edit":
|
case "system:aggregate-to-edit":
|
||||||
ret.edit = &role
|
ret.edit = &role
|
||||||
case "view":
|
case "system:aggregate-to-view":
|
||||||
ret.view = &role
|
ret.view = &role
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,8 +319,9 @@ func TestClusterRoleLabel(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if got, want := accessor.GetLabels(), map[string]string{"kubernetes.io/bootstrapping": "rbac-defaults"}; !reflect.DeepEqual(got, want) {
|
|
||||||
t.Errorf("ClusterRole: %s GetLabels() = %s, want %s", accessor.GetName(), got, want)
|
if accessor.GetLabels()["kubernetes.io/bootstrapping"] != "rbac-defaults" {
|
||||||
|
t.Errorf("ClusterRole: %s GetLabels() = %s, want %s", accessor.GetName(), accessor.GetLabels(), map[string]string{"kubernetes.io/bootstrapping": "rbac-defaults"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
items:
|
items:
|
||||||
- apiVersion: rbac.authorization.k8s.io/v1
|
- aggregationRule:
|
||||||
|
clusterRoleSelectors:
|
||||||
|
- matchLabels:
|
||||||
|
rbac.authorization.k8s.io/aggregate-to-admin: "true"
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
@ -9,6 +13,51 @@ items:
|
|||||||
labels:
|
labels:
|
||||||
kubernetes.io/bootstrapping: rbac-defaults
|
kubernetes.io/bootstrapping: rbac-defaults
|
||||||
name: admin
|
name: admin
|
||||||
|
rules: null
|
||||||
|
- apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
rbac.authorization.kubernetes.io/autoupdate: "true"
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
kubernetes.io/bootstrapping: rbac-defaults
|
||||||
|
name: cluster-admin
|
||||||
|
rules:
|
||||||
|
- apiGroups:
|
||||||
|
- '*'
|
||||||
|
resources:
|
||||||
|
- '*'
|
||||||
|
verbs:
|
||||||
|
- '*'
|
||||||
|
- nonResourceURLs:
|
||||||
|
- '*'
|
||||||
|
verbs:
|
||||||
|
- '*'
|
||||||
|
- aggregationRule:
|
||||||
|
clusterRoleSelectors:
|
||||||
|
- matchLabels:
|
||||||
|
rbac.authorization.k8s.io/aggregate-to-edit: "true"
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
rbac.authorization.kubernetes.io/autoupdate: "true"
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
kubernetes.io/bootstrapping: rbac-defaults
|
||||||
|
name: edit
|
||||||
|
rules: null
|
||||||
|
- apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
rbac.authorization.kubernetes.io/autoupdate: "true"
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
kubernetes.io/bootstrapping: rbac-defaults
|
||||||
|
rbac.authorization.k8s.io/aggregate-to-admin: "true"
|
||||||
|
name: system:aggregate-to-admin
|
||||||
rules:
|
rules:
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
@ -185,27 +234,8 @@ items:
|
|||||||
creationTimestamp: null
|
creationTimestamp: null
|
||||||
labels:
|
labels:
|
||||||
kubernetes.io/bootstrapping: rbac-defaults
|
kubernetes.io/bootstrapping: rbac-defaults
|
||||||
name: cluster-admin
|
rbac.authorization.k8s.io/aggregate-to-edit: "true"
|
||||||
rules:
|
name: system:aggregate-to-edit
|
||||||
- apiGroups:
|
|
||||||
- '*'
|
|
||||||
resources:
|
|
||||||
- '*'
|
|
||||||
verbs:
|
|
||||||
- '*'
|
|
||||||
- nonResourceURLs:
|
|
||||||
- '*'
|
|
||||||
verbs:
|
|
||||||
- '*'
|
|
||||||
- apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
rbac.authorization.kubernetes.io/autoupdate: "true"
|
|
||||||
creationTimestamp: null
|
|
||||||
labels:
|
|
||||||
kubernetes.io/bootstrapping: rbac-defaults
|
|
||||||
name: edit
|
|
||||||
rules:
|
rules:
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- ""
|
- ""
|
||||||
@ -354,6 +384,108 @@ items:
|
|||||||
- patch
|
- patch
|
||||||
- update
|
- update
|
||||||
- watch
|
- watch
|
||||||
|
- apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
rbac.authorization.kubernetes.io/autoupdate: "true"
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
kubernetes.io/bootstrapping: rbac-defaults
|
||||||
|
rbac.authorization.k8s.io/aggregate-to-view: "true"
|
||||||
|
name: system:aggregate-to-view
|
||||||
|
rules:
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- configmaps
|
||||||
|
- endpoints
|
||||||
|
- persistentvolumeclaims
|
||||||
|
- pods
|
||||||
|
- replicationcontrollers
|
||||||
|
- replicationcontrollers/scale
|
||||||
|
- serviceaccounts
|
||||||
|
- services
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- bindings
|
||||||
|
- events
|
||||||
|
- limitranges
|
||||||
|
- namespaces/status
|
||||||
|
- pods/log
|
||||||
|
- pods/status
|
||||||
|
- replicationcontrollers/status
|
||||||
|
- resourcequotas
|
||||||
|
- resourcequotas/status
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- ""
|
||||||
|
resources:
|
||||||
|
- namespaces
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- apps
|
||||||
|
resources:
|
||||||
|
- daemonsets
|
||||||
|
- deployments
|
||||||
|
- deployments/scale
|
||||||
|
- replicasets
|
||||||
|
- replicasets/scale
|
||||||
|
- statefulsets
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- autoscaling
|
||||||
|
resources:
|
||||||
|
- horizontalpodautoscalers
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- batch
|
||||||
|
resources:
|
||||||
|
- cronjobs
|
||||||
|
- jobs
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- extensions
|
||||||
|
resources:
|
||||||
|
- daemonsets
|
||||||
|
- deployments
|
||||||
|
- deployments/scale
|
||||||
|
- ingresses
|
||||||
|
- replicasets
|
||||||
|
- replicasets/scale
|
||||||
|
- replicationcontrollers/scale
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- policy
|
||||||
|
resources:
|
||||||
|
- poddisruptionbudgets
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- watch
|
||||||
- apiVersion: rbac.authorization.k8s.io/v1
|
- apiVersion: rbac.authorization.k8s.io/v1
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
metadata:
|
metadata:
|
||||||
@ -935,7 +1067,11 @@ items:
|
|||||||
- create
|
- create
|
||||||
- patch
|
- patch
|
||||||
- update
|
- update
|
||||||
- apiVersion: rbac.authorization.k8s.io/v1
|
- aggregationRule:
|
||||||
|
clusterRoleSelectors:
|
||||||
|
- matchLabels:
|
||||||
|
rbac.authorization.k8s.io/aggregate-to-view: "true"
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
@ -944,97 +1080,6 @@ items:
|
|||||||
labels:
|
labels:
|
||||||
kubernetes.io/bootstrapping: rbac-defaults
|
kubernetes.io/bootstrapping: rbac-defaults
|
||||||
name: view
|
name: view
|
||||||
rules:
|
rules: null
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- configmaps
|
|
||||||
- endpoints
|
|
||||||
- persistentvolumeclaims
|
|
||||||
- pods
|
|
||||||
- replicationcontrollers
|
|
||||||
- replicationcontrollers/scale
|
|
||||||
- serviceaccounts
|
|
||||||
- services
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- bindings
|
|
||||||
- events
|
|
||||||
- limitranges
|
|
||||||
- namespaces/status
|
|
||||||
- pods/log
|
|
||||||
- pods/status
|
|
||||||
- replicationcontrollers/status
|
|
||||||
- resourcequotas
|
|
||||||
- resourcequotas/status
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- namespaces
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
resources:
|
|
||||||
- daemonsets
|
|
||||||
- deployments
|
|
||||||
- deployments/scale
|
|
||||||
- replicasets
|
|
||||||
- replicasets/scale
|
|
||||||
- statefulsets
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- autoscaling
|
|
||||||
resources:
|
|
||||||
- horizontalpodautoscalers
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- batch
|
|
||||||
resources:
|
|
||||||
- cronjobs
|
|
||||||
- jobs
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- extensions
|
|
||||||
resources:
|
|
||||||
- daemonsets
|
|
||||||
- deployments
|
|
||||||
- deployments/scale
|
|
||||||
- ingresses
|
|
||||||
- replicasets
|
|
||||||
- replicasets/scale
|
|
||||||
- replicationcontrollers/scale
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- policy
|
|
||||||
resources:
|
|
||||||
- poddisruptionbudgets
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
kind: List
|
kind: List
|
||||||
metadata: {}
|
metadata: {}
|
||||||
|
@ -34,6 +34,23 @@ items:
|
|||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: certificate-controller
|
name: certificate-controller
|
||||||
namespace: kube-system
|
namespace: kube-system
|
||||||
|
- apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
rbac.authorization.kubernetes.io/autoupdate: "true"
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
kubernetes.io/bootstrapping: rbac-defaults
|
||||||
|
name: system:controller:clusterrole-aggregation-controller
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: system:controller:clusterrole-aggregation-controller
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: clusterrole-aggregation-controller
|
||||||
|
namespace: kube-system
|
||||||
- apiVersion: rbac.authorization.k8s.io/v1
|
- apiVersion: rbac.authorization.k8s.io/v1
|
||||||
kind: ClusterRoleBinding
|
kind: ClusterRoleBinding
|
||||||
metadata:
|
metadata:
|
||||||
|
@ -87,6 +87,26 @@ items:
|
|||||||
- create
|
- create
|
||||||
- patch
|
- patch
|
||||||
- update
|
- update
|
||||||
|
- apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
rbac.authorization.kubernetes.io/autoupdate: "true"
|
||||||
|
creationTimestamp: null
|
||||||
|
labels:
|
||||||
|
kubernetes.io/bootstrapping: rbac-defaults
|
||||||
|
name: system:controller:clusterrole-aggregation-controller
|
||||||
|
rules:
|
||||||
|
- apiGroups:
|
||||||
|
- '*'
|
||||||
|
resources:
|
||||||
|
- '*'
|
||||||
|
verbs:
|
||||||
|
- '*'
|
||||||
|
- nonResourceURLs:
|
||||||
|
- '*'
|
||||||
|
verbs:
|
||||||
|
- '*'
|
||||||
- apiVersion: rbac.authorization.k8s.io/v1
|
- apiVersion: rbac.authorization.k8s.io/v1
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
metadata:
|
metadata:
|
||||||
|
Loading…
Reference in New Issue
Block a user