From da3da292232d50f89fe47ad59980b01edb34d7fd Mon Sep 17 00:00:00 2001 From: deads2k Date: Wed, 22 Feb 2017 13:37:09 -0500 Subject: [PATCH] add kube-system local roles --- .../authorizer/rbac/bootstrappolicy/BUILD | 3 + .../rbac/bootstrappolicy/namespace_policy.go | 65 +++++++++++++++++++ .../authorizer/rbac/bootstrappolicy/policy.go | 56 ++++++++-------- .../rbac/bootstrappolicy/policy_test.go | 22 +++++++ .../testdata/namespace-roles.yaml | 23 +++++++ 5 files changed, 143 insertions(+), 26 deletions(-) create mode 100644 plugin/pkg/auth/authorizer/rbac/bootstrappolicy/namespace_policy.go create mode 100644 plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/namespace-roles.yaml diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/BUILD b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/BUILD index a3af80408ff..4c9524e6668 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/BUILD +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/BUILD @@ -12,13 +12,16 @@ go_library( name = "go_default_library", srcs = [ "controller_policy.go", + "namespace_policy.go", "policy.go", ], tags = ["automanaged"], deps = [ "//pkg/apis/rbac:go_default_library", "//vendor:github.com/golang/glog", + "//vendor:k8s.io/apimachinery/pkg/api/meta", "//vendor:k8s.io/apimachinery/pkg/apis/meta/v1", + "//vendor:k8s.io/apimachinery/pkg/runtime", "//vendor:k8s.io/apiserver/pkg/authentication/user", ], ) diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/namespace_policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/namespace_policy.go new file mode 100644 index 00000000000..35b9cae165c --- /dev/null +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/namespace_policy.go @@ -0,0 +1,65 @@ +/* +Copyright 2016 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 bootstrappolicy + +import ( + "strings" + + "github.com/golang/glog" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + rbac "k8s.io/kubernetes/pkg/apis/rbac" +) + +var ( + // namespaceRoles is a map of namespace to slice of roles to create + namespaceRoles = map[string][]rbac.Role{} +) + +func addNamespaceRole(namespace string, role rbac.Role) { + if !strings.HasPrefix(namespace, "kube-") { + glog.Fatalf(`roles can only be bootstrapped into reserved namespaces starting with "kube-", not %q`, namespace) + } + + existingRoles := namespaceRoles[namespace] + for _, existingRole := range existingRoles { + if role.Name == existingRole.Name { + glog.Fatalf("role %q was already registered in %q", role.Name, namespace) + } + } + + role.Namespace = namespace + addDefaultMetadata(&role) + existingRoles = append(existingRoles, role) + namespaceRoles[namespace] = existingRoles +} + +func init() { + addNamespaceRole(metav1.NamespaceSystem, rbac.Role{ + // role for finding authentication config info for starting a server + ObjectMeta: metav1.ObjectMeta{Name: "extension-apiserver-authentication-reader"}, + Rules: []rbac.PolicyRule{ + // this particular config map is exposed and contains authentication configuration information + rbac.NewRule("get").Groups(legacyGroup).Resources("configmaps").Names("extension-apiserver-authentication").RuleOrDie(), + }, + }) +} + +// NamespaceRoles returns a map of namespace to slice of roles to create +func NamespaceRoles() map[string][]rbac.Role { + return namespaceRoles +} diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go index 0694dbf0bfc..1c6d6e847c1 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go @@ -17,7 +17,9 @@ limitations under the License. package bootstrappolicy import ( + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/authentication/user" rbac "k8s.io/kubernetes/pkg/apis/rbac" ) @@ -44,40 +46,42 @@ const ( storageGroup = "storage.k8s.io" ) +func addDefaultMetadata(obj runtime.Object) { + metadata, err := meta.Accessor(obj) + if err != nil { + // if this happens, then some static code is broken + panic(err) + } + + labels := metadata.GetLabels() + if labels == nil { + labels = map[string]string{} + } + for k, v := range Label { + labels[k] = v + } + metadata.SetLabels(labels) + + annotations := metadata.GetAnnotations() + if annotations == nil { + annotations = map[string]string{} + } + for k, v := range Annotation { + annotations[k] = v + } + metadata.SetAnnotations(annotations) +} + func addClusterRoleLabel(roles []rbac.ClusterRole) { for i := range roles { - if roles[i].ObjectMeta.Labels == nil { - roles[i].ObjectMeta.Labels = make(map[string]string) - } - for k, v := range Label { - roles[i].ObjectMeta.Labels[k] = v - } - - if roles[i].ObjectMeta.Annotations == nil { - roles[i].ObjectMeta.Annotations = make(map[string]string) - } - for k, v := range Annotation { - roles[i].ObjectMeta.Annotations[k] = v - } + addDefaultMetadata(&roles[i]) } return } func addClusterRoleBindingLabel(rolebindings []rbac.ClusterRoleBinding) { for i := range rolebindings { - if rolebindings[i].ObjectMeta.Labels == nil { - rolebindings[i].ObjectMeta.Labels = make(map[string]string) - } - for k, v := range Label { - rolebindings[i].ObjectMeta.Labels[k] = v - } - - if rolebindings[i].ObjectMeta.Annotations == nil { - rolebindings[i].ObjectMeta.Annotations = make(map[string]string) - } - for k, v := range Annotation { - rolebindings[i].ObjectMeta.Annotations[k] = v - } + addDefaultMetadata(&rolebindings[i]) } return } diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go index 800a6884d75..22d0d2532ac 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy_test.go @@ -151,6 +151,28 @@ func TestEditViewRelationship(t *testing.T) { } } +func TestBootstrapNamespaceRoles(t *testing.T) { + list := &api.List{} + names := sets.NewString() + roles := map[string]runtime.Object{} + + namespaceRoles := bootstrappolicy.NamespaceRoles() + for _, namespace := range sets.StringKeySet(namespaceRoles).List() { + bootstrapRoles := namespaceRoles[namespace] + for i := range bootstrapRoles { + role := bootstrapRoles[i] + names.Insert(role.Name) + roles[role.Name] = &role + } + + for _, name := range names.List() { + list.Items = append(list.Items, roles[name]) + } + } + + testObjects(t, list, "namespace-roles.yaml") +} + func TestBootstrapClusterRoles(t *testing.T) { list := &api.List{} names := sets.NewString() diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/namespace-roles.yaml b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/namespace-roles.yaml new file mode 100644 index 00000000000..6f78b9a0769 --- /dev/null +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/namespace-roles.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +items: +- apiVersion: rbac.authorization.k8s.io/v1beta1 + kind: Role + metadata: + annotations: + rbac.authorization.kubernetes.io/autoupdate: "true" + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: extension-apiserver-authentication-reader + namespace: kube-system + rules: + - apiGroups: + - "" + resourceNames: + - extension-apiserver-authentication + resources: + - configmaps + verbs: + - get +kind: List +metadata: {}