mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 21:17:23 +00:00
add namespaced role bindings
This commit is contained in:
parent
a849df9dff
commit
e24b1c0c25
@ -282,6 +282,22 @@ func NewRoleBinding(roleName, namespace string) *RoleBindingBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewRoleBindingForClusterRole(roleName, namespace string) *RoleBindingBuilder {
|
||||||
|
return &RoleBindingBuilder{
|
||||||
|
RoleBinding: RoleBinding{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: roleName,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
RoleRef: RoleRef{
|
||||||
|
APIGroup: GroupName,
|
||||||
|
Kind: "ClusterRole",
|
||||||
|
Name: roleName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Groups adds the specified groups as the subjects of the RoleBinding.
|
// Groups adds the specified groups as the subjects of the RoleBinding.
|
||||||
func (r *RoleBindingBuilder) Groups(groups ...string) *RoleBindingBuilder {
|
func (r *RoleBindingBuilder) Groups(groups ...string) *RoleBindingBuilder {
|
||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
|
@ -233,6 +233,38 @@ func PostStartHook(hookContext genericapiserver.PostStartHookContext) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ensure bootstrap namespaced rolebindings are created or reconciled
|
||||||
|
for namespace, roleBindings := range bootstrappolicy.NamespaceRoleBindings() {
|
||||||
|
for _, roleBinding := range roleBindings {
|
||||||
|
opts := reconciliation.ReconcileRoleBindingOptions{
|
||||||
|
RoleBinding: reconciliation.RoleBindingAdapter{RoleBinding: &roleBinding},
|
||||||
|
Client: reconciliation.RoleBindingClientAdapter{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 rolebinding.%s/%s in %v with missing subjects: %v", rbac.GroupName, roleBinding.Name, namespace, result.MissingSubjects)
|
||||||
|
case result.Operation == reconciliation.ReconcileUpdate:
|
||||||
|
glog.Infof("updated rolebinding.%s/%s in %v with additional subjects: %v", rbac.GroupName, roleBinding.Name, namespace, result.MissingSubjects)
|
||||||
|
case result.Operation == reconciliation.ReconcileCreate:
|
||||||
|
glog.Infof("created rolebinding.%s/%s in %v", rbac.GroupName, roleBinding.Name, namespace)
|
||||||
|
case result.Operation == reconciliation.ReconcileRecreate:
|
||||||
|
glog.Infof("recreated rolebinding.%s/%s in %v", rbac.GroupName, roleBinding.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 rolebinding.%s/%s in %v: %v", rbac.GroupName, roleBinding.Name, namespace, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
})
|
})
|
||||||
// if we're never able to make it through intialization, kill the API server
|
// if we're never able to make it through intialization, kill the API server
|
||||||
|
@ -28,6 +28,9 @@ import (
|
|||||||
var (
|
var (
|
||||||
// namespaceRoles is a map of namespace to slice of roles to create
|
// namespaceRoles is a map of namespace to slice of roles to create
|
||||||
namespaceRoles = map[string][]rbac.Role{}
|
namespaceRoles = map[string][]rbac.Role{}
|
||||||
|
|
||||||
|
// namespaceRoleBindings is a map of namespace to slice of roleBindings to create
|
||||||
|
namespaceRoleBindings = map[string][]rbac.RoleBinding{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func addNamespaceRole(namespace string, role rbac.Role) {
|
func addNamespaceRole(namespace string, role rbac.Role) {
|
||||||
@ -48,6 +51,24 @@ func addNamespaceRole(namespace string, role rbac.Role) {
|
|||||||
namespaceRoles[namespace] = existingRoles
|
namespaceRoles[namespace] = existingRoles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addNamespaceRoleBinding(namespace string, roleBinding rbac.RoleBinding) {
|
||||||
|
if !strings.HasPrefix(namespace, "kube-") {
|
||||||
|
glog.Fatalf(`roles can only be bootstrapped into reserved namespaces starting with "kube-", not %q`, namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
existingRoleBindings := namespaceRoleBindings[namespace]
|
||||||
|
for _, existingRoleBinding := range existingRoleBindings {
|
||||||
|
if roleBinding.Name == existingRoleBinding.Name {
|
||||||
|
glog.Fatalf("rolebinding %q was already registered in %q", roleBinding.Name, namespace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
roleBinding.Namespace = namespace
|
||||||
|
addDefaultMetadata(&roleBinding)
|
||||||
|
existingRoleBindings = append(existingRoleBindings, roleBinding)
|
||||||
|
namespaceRoleBindings[namespace] = existingRoleBindings
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
addNamespaceRole(metav1.NamespaceSystem, rbac.Role{
|
addNamespaceRole(metav1.NamespaceSystem, rbac.Role{
|
||||||
// role for finding authentication config info for starting a server
|
// role for finding authentication config info for starting a server
|
||||||
@ -63,3 +84,8 @@ func init() {
|
|||||||
func NamespaceRoles() map[string][]rbac.Role {
|
func NamespaceRoles() map[string][]rbac.Role {
|
||||||
return namespaceRoles
|
return namespaceRoles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NamespaceRoleBindings returns a map of namespace to slice of roles to create
|
||||||
|
func NamespaceRoleBindings() map[string][]rbac.RoleBinding {
|
||||||
|
return namespaceRoleBindings
|
||||||
|
}
|
||||||
|
@ -173,6 +173,28 @@ func TestBootstrapNamespaceRoles(t *testing.T) {
|
|||||||
testObjects(t, list, "namespace-roles.yaml")
|
testObjects(t, list, "namespace-roles.yaml")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBootstrapNamespaceRoleBindings(t *testing.T) {
|
||||||
|
list := &api.List{}
|
||||||
|
names := sets.NewString()
|
||||||
|
roleBindings := map[string]runtime.Object{}
|
||||||
|
|
||||||
|
namespaceRoleBindings := bootstrappolicy.NamespaceRoleBindings()
|
||||||
|
for _, namespace := range sets.StringKeySet(namespaceRoleBindings).List() {
|
||||||
|
bootstrapRoleBindings := namespaceRoleBindings[namespace]
|
||||||
|
for i := range bootstrapRoleBindings {
|
||||||
|
roleBinding := bootstrapRoleBindings[i]
|
||||||
|
names.Insert(roleBinding.Name)
|
||||||
|
roleBindings[roleBinding.Name] = &roleBinding
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range names.List() {
|
||||||
|
list.Items = append(list.Items, roleBindings[name])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testObjects(t, list, "namespace-role-bindings.yaml")
|
||||||
|
}
|
||||||
|
|
||||||
func TestBootstrapClusterRoles(t *testing.T) {
|
func TestBootstrapClusterRoles(t *testing.T) {
|
||||||
list := &api.List{}
|
list := &api.List{}
|
||||||
names := sets.NewString()
|
names := sets.NewString()
|
||||||
|
4
plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/namespace-role-bindings.yaml
vendored
Normal file
4
plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/namespace-role-bindings.yaml
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
items: null
|
||||||
|
kind: List
|
||||||
|
metadata: {}
|
Loading…
Reference in New Issue
Block a user