mirror of https://github.com/k3s-io/k3s
reconcile namespace roles during startup
parent
da3da29223
commit
d5cd40a585
|
@ -11,8 +11,8 @@ load(
|
|||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"reconcile_clusterrole_test.go",
|
||||
"reconcile_clusterrolebindings_test.go",
|
||||
"reconcile_role_test.go",
|
||||
],
|
||||
library = ":go_default_library",
|
||||
tags = ["automanaged"],
|
||||
|
@ -26,8 +26,9 @@ go_test(
|
|||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"reconcile_clusterrole.go",
|
||||
"reconcile_clusterrolebindings.go",
|
||||
"reconcile_role.go",
|
||||
"role_interfaces.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package reconciliation
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion"
|
||||
)
|
||||
|
||||
type RoleRuleOwner struct {
|
||||
Role *rbac.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
|
||||
}
|
||||
|
||||
type RoleModifier struct {
|
||||
Client internalversion.RolesGetter
|
||||
}
|
||||
|
||||
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) {
|
||||
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()).Create(in.(RoleRuleOwner).Role)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return RoleRuleOwner{Role: ret}, err
|
||||
|
||||
}
|
|
@ -165,7 +165,6 @@ func PostStartHook(hookContext genericapiserver.PostStartHookContext) error {
|
|||
|
||||
// ensure bootstrap rolebindings are created or reconciled
|
||||
for _, clusterRoleBinding := range append(bootstrappolicy.ClusterRoleBindings(), bootstrappolicy.ControllerRoleBindings()...) {
|
||||
|
||||
opts := reconciliation.ReconcileClusterRoleBindingOptions{
|
||||
RoleBinding: &clusterRoleBinding,
|
||||
Client: clientset.ClusterRoleBindings(),
|
||||
|
@ -194,6 +193,36 @@ func PostStartHook(hookContext genericapiserver.PostStartHookContext) error {
|
|||
}
|
||||
}
|
||||
|
||||
// ensure bootstrap namespaced roles are created or reconciled
|
||||
for namespace, roles := range bootstrappolicy.NamespaceRoles() {
|
||||
for _, role := range roles {
|
||||
opts := reconciliation.ReconcileClusterRoleOptions{
|
||||
Role: reconciliation.RoleRuleOwner{Role: &role},
|
||||
Client: reconciliation.RoleModifier{Client: clientset},
|
||||
Confirm: true,
|
||||
}
|
||||
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
result, err := opts.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch {
|
||||
case result.Protected && result.Operation != reconciliation.ReconcileNone:
|
||||
glog.Warningf("skipped reconcile-protected role.%s/%s in %v with missing permissions: %v", rbac.GroupName, role.Name, namespace, result.MissingRules)
|
||||
case result.Operation == reconciliation.ReconcileUpdate:
|
||||
glog.Infof("updated role.%s/%s in %v with additional permissions: %v", rbac.GroupName, role.Name, namespace, result.MissingRules)
|
||||
case result.Operation == reconciliation.ReconcileCreate:
|
||||
glog.Infof("created role.%s/%s in %v ", rbac.GroupName, role.Name, namespace)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
// don't fail on failures, try to create as many as you can
|
||||
utilruntime.HandleError(fmt.Errorf("unable to reconcile role.%s/%s in %v: %v", rbac.GroupName, role.Name, namespace, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
})
|
||||
// if we're never able to make it through intialization, kill the API server
|
||||
|
|
Loading…
Reference in New Issue