switch rbac to external

This commit is contained in:
David Eads
2018-04-19 07:57:45 -04:00
parent 813021c1b1
commit 092714ea0f
58 changed files with 1319 additions and 1102 deletions

View File

@@ -42,7 +42,6 @@ go_library(
"//pkg/api/persistentvolume:go_default_library",
"//pkg/api/pod:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/apis/storage:go_default_library",
"//pkg/auth/nodeidentifier:go_default_library",
"//pkg/client/informers/informers_generated/internalversion/core/internalversion:go_default_library",
@@ -52,6 +51,7 @@ go_library(
"//third_party/forked/gonum/graph/simple:go_default_library",
"//third_party/forked/gonum/graph/traverse:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/api/rbac/v1:go_default_library",
"//vendor/k8s.io/api/storage/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",

View File

@@ -21,11 +21,11 @@ import (
"github.com/golang/glog"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/authorization/authorizer"
utilfeature "k8s.io/apiserver/pkg/util/feature"
api "k8s.io/kubernetes/pkg/apis/core"
rbacapi "k8s.io/kubernetes/pkg/apis/rbac"
storageapi "k8s.io/kubernetes/pkg/apis/storage"
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
"k8s.io/kubernetes/pkg/features"
@@ -49,14 +49,14 @@ import (
type NodeAuthorizer struct {
graph *Graph
identifier nodeidentifier.NodeIdentifier
nodeRules []rbacapi.PolicyRule
nodeRules []rbacv1.PolicyRule
// allows overriding for testing
features utilfeature.FeatureGate
}
// NewAuthorizer returns a new node authorizer
func NewAuthorizer(graph *Graph, identifier nodeidentifier.NodeIdentifier, rules []rbacapi.PolicyRule) authorizer.Authorizer {
func NewAuthorizer(graph *Graph, identifier nodeidentifier.NodeIdentifier, rules []rbacv1.PolicyRule) authorizer.Authorizer {
return &NodeAuthorizer{
graph: graph,
identifier: identifier,

View File

@@ -14,14 +14,15 @@ go_library(
],
importpath = "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac",
deps = [
"//pkg/apis/rbac:go_default_library",
"//pkg/client/listers/rbac/internalversion:go_default_library",
"//pkg/apis/rbac/v1:go_default_library",
"//pkg/registry/rbac/validation:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/api/rbac/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
"//vendor/k8s.io/client-go/listers/rbac/v1:go_default_library",
],
)
@@ -33,9 +34,10 @@ go_test(
],
embed = [":go_default_library"],
deps = [
"//pkg/apis/rbac:go_default_library",
"//pkg/apis/rbac/v1:go_default_library",
"//pkg/registry/rbac/validation:go_default_library",
"//plugin/pkg/auth/authorizer/rbac/bootstrappolicy:go_default_library",
"//vendor/k8s.io/api/rbac/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",

View File

@@ -15,9 +15,10 @@ go_library(
],
importpath = "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy",
deps = [
"//pkg/apis/rbac:go_default_library",
"//pkg/apis/rbac/v1:go_default_library",
"//pkg/features:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/api/rbac/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
@@ -37,8 +38,8 @@ go_test(
"//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/apis/core/install:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/apis/rbac/install:go_default_library",
"//pkg/apis/rbac/v1:go_default_library",
"//pkg/registry/rbac/validation:go_default_library",
"//vendor/github.com/ghodss/yaml:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",

View File

@@ -21,15 +21,16 @@ import (
"github.com/golang/glog"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature"
rbac "k8s.io/kubernetes/pkg/apis/rbac"
rbacv1helpers "k8s.io/kubernetes/pkg/apis/rbac/v1"
"k8s.io/kubernetes/pkg/features"
)
const saRolePrefix = "system:controller:"
func addControllerRole(controllerRoles *[]rbac.ClusterRole, controllerRoleBindings *[]rbac.ClusterRoleBinding, role rbac.ClusterRole) {
func addControllerRole(controllerRoles *[]rbacv1.ClusterRole, controllerRoleBindings *[]rbacv1.ClusterRoleBinding, role rbacv1.ClusterRole) {
if !strings.HasPrefix(role.Name, saRolePrefix) {
glog.Fatalf(`role %q must start with %q`, role.Name, saRolePrefix)
}
@@ -44,298 +45,298 @@ func addControllerRole(controllerRoles *[]rbac.ClusterRole, controllerRoleBindin
addClusterRoleLabel(*controllerRoles)
*controllerRoleBindings = append(*controllerRoleBindings,
rbac.NewClusterBinding(role.Name).SAs("kube-system", role.Name[len(saRolePrefix):]).BindingOrDie())
rbacv1helpers.NewClusterBinding(role.Name).SAs("kube-system", role.Name[len(saRolePrefix):]).BindingOrDie())
addClusterRoleBindingLabel(*controllerRoleBindings)
}
func eventsRule() rbac.PolicyRule {
return rbac.NewRule("create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie()
func eventsRule() rbacv1.PolicyRule {
return rbacv1helpers.NewRule("create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie()
}
func buildControllerRoles() ([]rbac.ClusterRole, []rbac.ClusterRoleBinding) {
func buildControllerRoles() ([]rbacv1.ClusterRole, []rbacv1.ClusterRoleBinding) {
// controllerRoles is a slice of roles used for controllers
controllerRoles := []rbac.ClusterRole{}
controllerRoles := []rbacv1.ClusterRole{}
// controllerRoleBindings is a slice of roles used for controllers
controllerRoleBindings := []rbac.ClusterRoleBinding{}
controllerRoleBindings := []rbacv1.ClusterRoleBinding{}
addControllerRole(&controllerRoles, &controllerRoleBindings, func() rbac.ClusterRole {
role := rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, func() rbacv1.ClusterRole {
role := rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "attachdetach-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("list", "watch").Groups(legacyGroup).Resources("persistentvolumes", "persistentvolumeclaims").RuleOrDie(),
rbac.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbac.NewRule("patch", "update").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
rbac.NewRule("list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("persistentvolumes", "persistentvolumeclaims").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("patch", "update").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
eventsRule(),
},
}
if utilfeature.DefaultFeatureGate.Enabled(features.CSIPersistentVolume) {
role.Rules = append(role.Rules, rbac.NewRule("get", "create", "delete", "list", "watch").Groups(storageGroup).Resources("volumeattachments").RuleOrDie())
role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "create", "delete", "list", "watch").Groups(storageGroup).Resources("volumeattachments").RuleOrDie())
}
return role
}())
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "clusterrole-aggregation-controller"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.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(),
rbacv1helpers.NewRule("*").Groups("*").Resources("*").RuleOrDie(),
rbacv1helpers.NewRule("*").URLs("*").RuleOrDie(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "cronjob-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "update").Groups(batchGroup).Resources("cronjobs").RuleOrDie(),
rbac.NewRule("get", "list", "watch", "create", "update", "delete", "patch").Groups(batchGroup).Resources("jobs").RuleOrDie(),
rbac.NewRule("update").Groups(batchGroup).Resources("cronjobs/status").RuleOrDie(),
rbac.NewRule("update").Groups(batchGroup).Resources("cronjobs/finalizers").RuleOrDie(),
rbac.NewRule("list", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(batchGroup).Resources("cronjobs").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "delete", "patch").Groups(batchGroup).Resources("jobs").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("cronjobs/status").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("cronjobs/finalizers").RuleOrDie(),
rbacv1helpers.NewRule("list", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "daemon-set-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch").Groups(extensionsGroup, appsGroup).Resources("daemonsets").RuleOrDie(),
rbac.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("daemonsets/status").RuleOrDie(),
rbac.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("daemonsets/finalizers").RuleOrDie(),
rbac.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbac.NewRule("list", "watch", "create", "delete", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbac.NewRule("create").Groups(legacyGroup).Resources("pods/binding").RuleOrDie(),
rbac.NewRule("get", "list", "watch", "create", "delete", "update", "patch").Groups(appsGroup).Resources("controllerrevisions").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch").Groups(extensionsGroup, appsGroup).Resources("daemonsets").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("daemonsets/status").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("daemonsets/finalizers").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch", "create", "delete", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("pods/binding").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "create", "delete", "update", "patch").Groups(appsGroup).Resources("controllerrevisions").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "deployment-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "update").Groups(extensionsGroup, appsGroup).Resources("deployments").RuleOrDie(),
rbac.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("deployments/status").RuleOrDie(),
rbac.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("deployments/finalizers").RuleOrDie(),
rbac.NewRule("get", "list", "watch", "create", "update", "patch", "delete").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(extensionsGroup, appsGroup).Resources("deployments").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("deployments/status").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(extensionsGroup, appsGroup).Resources("deployments/finalizers").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "patch", "delete").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
// TODO: remove "update" once
// https://github.com/kubernetes/kubernetes/issues/36897 is resolved.
rbac.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("pods").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "disruption-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch").Groups(extensionsGroup, appsGroup).Resources("deployments").RuleOrDie(),
rbac.NewRule("get", "list", "watch").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
rbac.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("replicationcontrollers").RuleOrDie(),
rbac.NewRule("get", "list", "watch").Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
rbac.NewRule("get", "list", "watch").Groups(appsGroup).Resources("statefulsets").RuleOrDie(),
rbac.NewRule("update").Groups(policyGroup).Resources("poddisruptionbudgets/status").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch").Groups(extensionsGroup, appsGroup).Resources("deployments").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("replicationcontrollers").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(appsGroup).Resources("statefulsets").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(policyGroup).Resources("poddisruptionbudgets/status").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "endpoint-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("services", "pods").RuleOrDie(),
rbac.NewRule("get", "list", "create", "update", "delete").Groups(legacyGroup).Resources("endpoints").RuleOrDie(),
rbac.NewRule("create").Groups(legacyGroup).Resources("endpoints/restricted").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("services", "pods").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "create", "update", "delete").Groups(legacyGroup).Resources("endpoints").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("endpoints/restricted").RuleOrDie(),
eventsRule(),
},
})
if utilfeature.DefaultFeatureGate.Enabled(features.ExpandPersistentVolumes) {
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "expand-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
rbac.NewRule("update", "patch").Groups(legacyGroup).Resources("persistentvolumeclaims/status").RuleOrDie(),
rbac.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
rbacv1helpers.NewRule("update", "patch").Groups(legacyGroup).Resources("persistentvolumeclaims/status").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
// glusterfs
rbac.NewRule("get", "list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
rbac.NewRule("get").Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(),
rbac.NewRule("get").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(),
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
eventsRule(),
},
})
}
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "generic-garbage-collector"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
// the GC controller needs to run list/watches, selective gets, and updates against any resource
rbac.NewRule("get", "list", "watch", "patch", "update", "delete").Groups("*").Resources("*").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "patch", "update", "delete").Groups("*").Resources("*").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "horizontal-pod-autoscaler"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch").Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
rbac.NewRule("update").Groups(autoscalingGroup).Resources("horizontalpodautoscalers/status").RuleOrDie(),
rbac.NewRule("get", "update").Groups("*").Resources("*/scale").RuleOrDie(),
rbac.NewRule("list").Groups(legacyGroup).Resources("pods").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch").Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(autoscalingGroup).Resources("horizontalpodautoscalers/status").RuleOrDie(),
rbacv1helpers.NewRule("get", "update").Groups("*").Resources("*/scale").RuleOrDie(),
rbacv1helpers.NewRule("list").Groups(legacyGroup).Resources("pods").RuleOrDie(),
// TODO: restrict this to the appropriate namespace
rbac.NewRule("get").Groups(legacyGroup).Resources("services/proxy").Names("https:heapster:", "http:heapster:").RuleOrDie(),
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("services/proxy").Names("https:heapster:", "http:heapster:").RuleOrDie(),
// allow listing resource metrics and custom metrics
rbac.NewRule("list").Groups(resMetricsGroup).Resources("pods").RuleOrDie(),
rbac.NewRule("get", "list").Groups(customMetricsGroup).Resources("*").RuleOrDie(),
rbacv1helpers.NewRule("list").Groups(resMetricsGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("get", "list").Groups(customMetricsGroup).Resources("*").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "job-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "update").Groups(batchGroup).Resources("jobs").RuleOrDie(),
rbac.NewRule("update").Groups(batchGroup).Resources("jobs/status").RuleOrDie(),
rbac.NewRule("update").Groups(batchGroup).Resources("jobs/finalizers").RuleOrDie(),
rbac.NewRule("list", "watch", "create", "delete", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(batchGroup).Resources("jobs").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("jobs/status").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(batchGroup).Resources("jobs/finalizers").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch", "create", "delete", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "namespace-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "delete").Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
rbac.NewRule("update").Groups(legacyGroup).Resources("namespaces/finalize", "namespaces/status").RuleOrDie(),
rbac.NewRule("get", "list", "delete", "deletecollection").Groups("*").Resources("*").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("namespaces/finalize", "namespaces/status").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "delete", "deletecollection").Groups("*").Resources("*").RuleOrDie(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "node-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "update", "delete", "patch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbac.NewRule("patch", "update").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "update", "delete", "patch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("patch", "update").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
// used for pod eviction
rbac.NewRule("update").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
rbac.NewRule("list", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
rbacv1helpers.NewRule("list", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "persistent-volume-binder"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "update", "create", "delete").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
rbac.NewRule("update").Groups(legacyGroup).Resources("persistentvolumes/status").RuleOrDie(),
rbac.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
rbac.NewRule("update").Groups(legacyGroup).Resources("persistentvolumeclaims/status").RuleOrDie(),
rbac.NewRule("list", "watch", "get", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "update", "create", "delete").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("persistentvolumes/status").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("persistentvolumeclaims/status").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch", "get", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
// glusterfs
rbac.NewRule("get", "list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
rbac.NewRule("get", "create", "delete").Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(),
rbac.NewRule("get").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
rbacv1helpers.NewRule("get", "create", "delete").Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(),
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
// openstack
rbac.NewRule("get", "list").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("get", "list").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
// recyclerClient.WatchPod
rbac.NewRule("watch").Groups(legacyGroup).Resources("events").RuleOrDie(),
rbacv1helpers.NewRule("watch").Groups(legacyGroup).Resources("events").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "pod-garbage-collector"},
Rules: []rbac.PolicyRule{
rbac.NewRule("list", "watch", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbac.NewRule("list").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("list", "watch", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("list").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "replicaset-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "update").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
rbac.NewRule("update").Groups(appsGroup, extensionsGroup).Resources("replicasets/status").RuleOrDie(),
rbac.NewRule("update").Groups(appsGroup, extensionsGroup).Resources("replicasets/finalizers").RuleOrDie(),
rbac.NewRule("list", "watch", "patch", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(appsGroup, extensionsGroup).Resources("replicasets/status").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(appsGroup, extensionsGroup).Resources("replicasets/finalizers").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch", "patch", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "replication-controller"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
// 1.0 controllers needed get, update, so without these old controllers break on new servers
rbac.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("replicationcontrollers").RuleOrDie(),
rbac.NewRule("update").Groups(legacyGroup).Resources("replicationcontrollers/status").RuleOrDie(),
rbac.NewRule("update").Groups(legacyGroup).Resources("replicationcontrollers/finalizers").RuleOrDie(),
rbac.NewRule("list", "watch", "patch", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("replicationcontrollers").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("replicationcontrollers/status").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("replicationcontrollers/finalizers").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch", "patch", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "resourcequota-controller"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
// quota can count quota on anything for reconciliation, so it needs full viewing powers
rbac.NewRule("list", "watch").Groups("*").Resources("*").RuleOrDie(),
rbac.NewRule("update").Groups(legacyGroup).Resources("resourcequotas/status").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch").Groups("*").Resources("*").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("resourcequotas/status").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "route-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbac.NewRule("patch").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("patch").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "service-account-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("create").Groups(legacyGroup).Resources("serviceaccounts").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("serviceaccounts").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "service-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("services").RuleOrDie(),
rbac.NewRule("update").Groups(legacyGroup).Resources("services/status").RuleOrDie(),
rbac.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("services").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("services/status").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "statefulset-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbac.NewRule("get", "list", "watch").Groups(appsGroup).Resources("statefulsets").RuleOrDie(),
rbac.NewRule("update").Groups(appsGroup).Resources("statefulsets/status").RuleOrDie(),
rbac.NewRule("update").Groups(appsGroup).Resources("statefulsets/finalizers").RuleOrDie(),
rbac.NewRule("get", "create", "delete", "update", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbac.NewRule("get", "create", "delete", "update", "patch", "list", "watch").Groups(appsGroup).Resources("controllerrevisions").RuleOrDie(),
rbac.NewRule("get", "create").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(appsGroup).Resources("statefulsets").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(appsGroup).Resources("statefulsets/status").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(appsGroup).Resources("statefulsets/finalizers").RuleOrDie(),
rbacv1helpers.NewRule("get", "create", "delete", "update", "patch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("get", "create", "delete", "update", "patch", "list", "watch").Groups(appsGroup).Resources("controllerrevisions").RuleOrDie(),
rbacv1helpers.NewRule("get", "create").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "ttl-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("update", "patch", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("update", "patch", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "certificate-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "delete").Groups(certificatesGroup).Resources("certificatesigningrequests").RuleOrDie(),
rbac.NewRule("update").Groups(certificatesGroup).Resources("certificatesigningrequests/status", "certificatesigningrequests/approval").RuleOrDie(),
rbac.NewRule("create").Groups(authorizationGroup).Resources("subjectaccessreviews").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(certificatesGroup).Resources("certificatesigningrequests").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(certificatesGroup).Resources("certificatesigningrequests/status", "certificatesigningrequests/approval").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(authorizationGroup).Resources("subjectaccessreviews").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "pvc-protection-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
rbac.NewRule("list", "watch", "get").Groups(legacyGroup).Resources("pods").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch", "get").Groups(legacyGroup).Resources("pods").RuleOrDie(),
eventsRule(),
},
})
addControllerRole(&controllerRoles, &controllerRoleBindings, rbac.ClusterRole{
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "pv-protection-controller"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
eventsRule(),
},
})
@@ -344,13 +345,13 @@ func buildControllerRoles() ([]rbac.ClusterRole, []rbac.ClusterRoleBinding) {
}
// ControllerRoles returns the cluster roles used by controllers
func ControllerRoles() []rbac.ClusterRole {
func ControllerRoles() []rbacv1.ClusterRole {
controllerRoles, _ := buildControllerRoles()
return controllerRoles
}
// ControllerRoleBindings returns the role bindings used by controllers
func ControllerRoleBindings() []rbac.ClusterRoleBinding {
func ControllerRoleBindings() []rbacv1.ClusterRoleBinding {
_, controllerRoleBindings := buildControllerRoles()
return controllerRoleBindings
}

View File

@@ -21,19 +21,20 @@ import (
"github.com/golang/glog"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
rbac "k8s.io/kubernetes/pkg/apis/rbac"
rbacv1helpers "k8s.io/kubernetes/pkg/apis/rbac/v1"
)
var (
// namespaceRoles is a map of namespace to slice of roles to create
namespaceRoles = map[string][]rbac.Role{}
namespaceRoles = map[string][]rbacv1.Role{}
// namespaceRoleBindings is a map of namespace to slice of roleBindings to create
namespaceRoleBindings = map[string][]rbac.RoleBinding{}
namespaceRoleBindings = map[string][]rbacv1.RoleBinding{}
)
func addNamespaceRole(namespace string, role rbac.Role) {
func addNamespaceRole(namespace string, role rbacv1.Role) {
if !strings.HasPrefix(namespace, "kube-") {
glog.Fatalf(`roles can only be bootstrapped into reserved namespaces starting with "kube-", not %q`, namespace)
}
@@ -51,7 +52,7 @@ func addNamespaceRole(namespace string, role rbac.Role) {
namespaceRoles[namespace] = existingRoles
}
func addNamespaceRoleBinding(namespace string, roleBinding rbac.RoleBinding) {
func addNamespaceRoleBinding(namespace string, roleBinding rbacv1.RoleBinding) {
if !strings.HasPrefix(namespace, "kube-") {
glog.Fatalf(`rolebindings can only be bootstrapped into reserved namespaces starting with "kube-", not %q`, namespace)
}
@@ -70,86 +71,86 @@ func addNamespaceRoleBinding(namespace string, roleBinding rbac.RoleBinding) {
}
func init() {
addNamespaceRole(metav1.NamespaceSystem, rbac.Role{
addNamespaceRole(metav1.NamespaceSystem, rbacv1.Role{
// role for finding authentication config info for starting a server
ObjectMeta: metav1.ObjectMeta{Name: "extension-apiserver-authentication-reader"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
// this particular config map is exposed and contains authentication configuration information
rbac.NewRule("get").Groups(legacyGroup).Resources("configmaps").Names("extension-apiserver-authentication").RuleOrDie(),
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("configmaps").Names("extension-apiserver-authentication").RuleOrDie(),
},
})
addNamespaceRole(metav1.NamespaceSystem, rbac.Role{
addNamespaceRole(metav1.NamespaceSystem, rbacv1.Role{
// role for the bootstrap signer to be able to inspect kube-system secrets
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "bootstrap-signer"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
},
})
addNamespaceRole(metav1.NamespaceSystem, rbac.Role{
addNamespaceRole(metav1.NamespaceSystem, rbacv1.Role{
// role for the cloud providers to access/create kube-system configmaps
// Deprecated starting Kubernetes 1.10 and will be deleted according to GA deprecation policy.
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "cloud-provider"},
Rules: []rbac.PolicyRule{
rbac.NewRule("create", "get", "list", "watch").Groups(legacyGroup).Resources("configmaps").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("create", "get", "list", "watch").Groups(legacyGroup).Resources("configmaps").RuleOrDie(),
},
})
addNamespaceRole(metav1.NamespaceSystem, rbac.Role{
addNamespaceRole(metav1.NamespaceSystem, rbacv1.Role{
// role for the token-cleaner to be able to remove secrets, but only in kube-system
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "token-cleaner"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "delete").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
eventsRule(),
},
})
// TODO: Create util on Role+Binding for leader locking if more cases evolve.
addNamespaceRole(metav1.NamespaceSystem, rbac.Role{
addNamespaceRole(metav1.NamespaceSystem, rbacv1.Role{
// role for the leader locking on supplied configmap
ObjectMeta: metav1.ObjectMeta{Name: "system::leader-locking-kube-controller-manager"},
Rules: []rbac.PolicyRule{
rbac.NewRule("watch").Groups(legacyGroup).Resources("configmaps").RuleOrDie(),
rbac.NewRule("get", "update").Groups(legacyGroup).Resources("configmaps").Names("kube-controller-manager").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("watch").Groups(legacyGroup).Resources("configmaps").RuleOrDie(),
rbacv1helpers.NewRule("get", "update").Groups(legacyGroup).Resources("configmaps").Names("kube-controller-manager").RuleOrDie(),
},
})
addNamespaceRole(metav1.NamespaceSystem, rbac.Role{
addNamespaceRole(metav1.NamespaceSystem, rbacv1.Role{
// role for the leader locking on supplied configmap
ObjectMeta: metav1.ObjectMeta{Name: "system::leader-locking-kube-scheduler"},
Rules: []rbac.PolicyRule{
rbac.NewRule("watch").Groups(legacyGroup).Resources("configmaps").RuleOrDie(),
rbac.NewRule("get", "update").Groups(legacyGroup).Resources("configmaps").Names("kube-scheduler").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("watch").Groups(legacyGroup).Resources("configmaps").RuleOrDie(),
rbacv1helpers.NewRule("get", "update").Groups(legacyGroup).Resources("configmaps").Names("kube-scheduler").RuleOrDie(),
},
})
addNamespaceRoleBinding(metav1.NamespaceSystem,
rbac.NewRoleBinding("system::leader-locking-kube-controller-manager", metav1.NamespaceSystem).SAs(metav1.NamespaceSystem, "kube-controller-manager").BindingOrDie())
rbacv1helpers.NewRoleBinding("system::leader-locking-kube-controller-manager", metav1.NamespaceSystem).SAs(metav1.NamespaceSystem, "kube-controller-manager").BindingOrDie())
addNamespaceRoleBinding(metav1.NamespaceSystem,
rbac.NewRoleBinding("system::leader-locking-kube-scheduler", metav1.NamespaceSystem).SAs(metav1.NamespaceSystem, "kube-scheduler").BindingOrDie())
rbacv1helpers.NewRoleBinding("system::leader-locking-kube-scheduler", metav1.NamespaceSystem).SAs(metav1.NamespaceSystem, "kube-scheduler").BindingOrDie())
addNamespaceRoleBinding(metav1.NamespaceSystem,
rbac.NewRoleBinding(saRolePrefix+"bootstrap-signer", metav1.NamespaceSystem).SAs(metav1.NamespaceSystem, "bootstrap-signer").BindingOrDie())
rbacv1helpers.NewRoleBinding(saRolePrefix+"bootstrap-signer", metav1.NamespaceSystem).SAs(metav1.NamespaceSystem, "bootstrap-signer").BindingOrDie())
// cloud-provider is deprecated starting Kubernetes 1.10 and will be deleted according to GA deprecation policy.
addNamespaceRoleBinding(metav1.NamespaceSystem,
rbac.NewRoleBinding(saRolePrefix+"cloud-provider", metav1.NamespaceSystem).SAs(metav1.NamespaceSystem, "cloud-provider").BindingOrDie())
rbacv1helpers.NewRoleBinding(saRolePrefix+"cloud-provider", metav1.NamespaceSystem).SAs(metav1.NamespaceSystem, "cloud-provider").BindingOrDie())
addNamespaceRoleBinding(metav1.NamespaceSystem,
rbac.NewRoleBinding(saRolePrefix+"token-cleaner", metav1.NamespaceSystem).SAs(metav1.NamespaceSystem, "token-cleaner").BindingOrDie())
rbacv1helpers.NewRoleBinding(saRolePrefix+"token-cleaner", metav1.NamespaceSystem).SAs(metav1.NamespaceSystem, "token-cleaner").BindingOrDie())
addNamespaceRole(metav1.NamespacePublic, rbac.Role{
addNamespaceRole(metav1.NamespacePublic, rbacv1.Role{
// role for the bootstrap signer to be able to write its configmap
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "bootstrap-signer"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("configmaps").RuleOrDie(),
rbac.NewRule("update").Groups(legacyGroup).Resources("configmaps").Names("cluster-info").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("configmaps").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("configmaps").Names("cluster-info").RuleOrDie(),
eventsRule(),
},
})
addNamespaceRoleBinding(metav1.NamespacePublic,
rbac.NewRoleBinding(saRolePrefix+"bootstrap-signer", metav1.NamespacePublic).SAs(metav1.NamespaceSystem, "bootstrap-signer").BindingOrDie())
rbacv1helpers.NewRoleBinding(saRolePrefix+"bootstrap-signer", metav1.NamespacePublic).SAs(metav1.NamespaceSystem, "bootstrap-signer").BindingOrDie())
}
// NamespaceRoles returns a map of namespace to slice of roles to create
func NamespaceRoles() map[string][]rbac.Role {
func NamespaceRoles() map[string][]rbacv1.Role {
return namespaceRoles
}
// NamespaceRoleBindings returns a map of namespace to slice of roles to create
func NamespaceRoleBindings() map[string][]rbac.RoleBinding {
func NamespaceRoleBindings() map[string][]rbacv1.RoleBinding {
return namespaceRoleBindings
}

View File

@@ -17,12 +17,13 @@ limitations under the License.
package bootstrappolicy
import (
rbacv1 "k8s.io/api/rbac/v1"
"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"
utilfeature "k8s.io/apiserver/pkg/util/feature"
rbac "k8s.io/kubernetes/pkg/apis/rbac"
rbacv1helpers "k8s.io/kubernetes/pkg/apis/rbac/v1"
"k8s.io/kubernetes/pkg/features"
)
@@ -32,7 +33,7 @@ var (
ReadUpdate = []string{"get", "list", "watch", "update", "patch"}
Label = map[string]string{"kubernetes.io/bootstrapping": "rbac-defaults"}
Annotation = map[string]string{rbac.AutoUpdateAnnotationKey: "true"}
Annotation = map[string]string{rbacv1.AutoUpdateAnnotationKey: "true"}
)
const (
@@ -78,105 +79,105 @@ func addDefaultMetadata(obj runtime.Object) {
metadata.SetAnnotations(annotations)
}
func addClusterRoleLabel(roles []rbac.ClusterRole) {
func addClusterRoleLabel(roles []rbacv1.ClusterRole) {
for i := range roles {
addDefaultMetadata(&roles[i])
}
return
}
func addClusterRoleBindingLabel(rolebindings []rbac.ClusterRoleBinding) {
func addClusterRoleBindingLabel(rolebindings []rbacv1.ClusterRoleBinding) {
for i := range rolebindings {
addDefaultMetadata(&rolebindings[i])
}
return
}
func NodeRules() []rbac.PolicyRule {
nodePolicyRules := []rbac.PolicyRule{
func NodeRules() []rbacv1.PolicyRule {
nodePolicyRules := []rbacv1.PolicyRule{
// Needed to check API access. These creates are non-mutating
rbac.NewRule("create").Groups(authenticationGroup).Resources("tokenreviews").RuleOrDie(),
rbac.NewRule("create").Groups(authorizationGroup).Resources("subjectaccessreviews", "localsubjectaccessreviews").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(authenticationGroup).Resources("tokenreviews").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(authorizationGroup).Resources("subjectaccessreviews", "localsubjectaccessreviews").RuleOrDie(),
// Needed to build serviceLister, to populate env vars for services
rbac.NewRule(Read...).Groups(legacyGroup).Resources("services").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("services").RuleOrDie(),
// Nodes can register Node API objects and report status.
// Use the NodeRestriction admission plugin to limit a node to creating/updating its own API object.
rbac.NewRule("create", "get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbac.NewRule("update", "patch").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
rbac.NewRule("update", "patch", "delete").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("create", "get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("update", "patch").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
rbacv1helpers.NewRule("update", "patch", "delete").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
// TODO: restrict to the bound node as creator in the NodeRestrictions admission plugin
rbac.NewRule("create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie(),
rbacv1helpers.NewRule("create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie(),
// TODO: restrict to pods scheduled on the bound node once field selectors are supported by list/watch authorization
rbac.NewRule(Read...).Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("pods").RuleOrDie(),
// Needed for the node to create/delete mirror pods.
// Use the NodeRestriction admission plugin to limit a node to creating/deleting mirror pods bound to itself.
rbac.NewRule("create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
// Needed for the node to report status of pods it is running.
// Use the NodeRestriction admission plugin to limit a node to updating status of pods bound to itself.
rbac.NewRule("update").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
// Needed for the node to create pod evictions.
// Use the NodeRestriction admission plugin to limit a node to creating evictions for pods bound to itself.
rbac.NewRule("create").Groups(legacyGroup).Resources("pods/eviction").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("pods/eviction").RuleOrDie(),
// Needed for imagepullsecrets, rbd/ceph and secret volumes, and secrets in envs
// Needed for configmap volume and envs
// Use the Node authorization mode to limit a node to get secrets/configmaps referenced by pods bound to itself.
rbac.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("secrets", "configmaps").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("secrets", "configmaps").RuleOrDie(),
// Needed for persistent volumes
// Use the Node authorization mode to limit a node to get pv/pvc objects referenced by pods bound to itself.
rbac.NewRule("get").Groups(legacyGroup).Resources("persistentvolumeclaims", "persistentvolumes").RuleOrDie(),
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("persistentvolumeclaims", "persistentvolumes").RuleOrDie(),
// TODO: add to the Node authorizer and restrict to endpoints referenced by pods or PVs bound to the node
// Needed for glusterfs volumes
rbac.NewRule("get").Groups(legacyGroup).Resources("endpoints").RuleOrDie(),
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("endpoints").RuleOrDie(),
// Used to create a certificatesigningrequest for a node-specific client certificate, and watch
// for it to be signed. This allows the kubelet to rotate it's own certificate.
rbac.NewRule("create", "get", "list", "watch").Groups(certificatesGroup).Resources("certificatesigningrequests").RuleOrDie(),
rbacv1helpers.NewRule("create", "get", "list", "watch").Groups(certificatesGroup).Resources("certificatesigningrequests").RuleOrDie(),
}
if utilfeature.DefaultFeatureGate.Enabled(features.ExpandPersistentVolumes) {
// Use the Node authorization mode to limit a node to update status of pvc objects referenced by pods bound to itself.
// Use the NodeRestriction admission plugin to limit a node to just update the status stanza.
pvcStatusPolicyRule := rbac.NewRule("get", "update", "patch").Groups(legacyGroup).Resources("persistentvolumeclaims/status").RuleOrDie()
pvcStatusPolicyRule := rbacv1helpers.NewRule("get", "update", "patch").Groups(legacyGroup).Resources("persistentvolumeclaims/status").RuleOrDie()
nodePolicyRules = append(nodePolicyRules, pvcStatusPolicyRule)
}
if utilfeature.DefaultFeatureGate.Enabled(features.TokenRequest) {
// Use the Node authorization to limit a node to create tokens for service accounts running on that node
// Use the NodeRestriction admission plugin to limit a node to create tokens bound to pods on that node
tokenRequestRule := rbac.NewRule("create").Groups(legacyGroup).Resources("serviceaccounts/token").RuleOrDie()
tokenRequestRule := rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("serviceaccounts/token").RuleOrDie()
nodePolicyRules = append(nodePolicyRules, tokenRequestRule)
}
// CSI
if utilfeature.DefaultFeatureGate.Enabled(features.CSIPersistentVolume) {
volAttachRule := rbac.NewRule("get").Groups(storageGroup).Resources("volumeattachments").RuleOrDie()
volAttachRule := rbacv1helpers.NewRule("get").Groups(storageGroup).Resources("volumeattachments").RuleOrDie()
nodePolicyRules = append(nodePolicyRules, volAttachRule)
}
return nodePolicyRules
}
// ClusterRoles returns the cluster roles to bootstrap an API server with
func ClusterRoles() []rbac.ClusterRole {
roles := []rbac.ClusterRole{
func ClusterRoles() []rbacv1.ClusterRole {
roles := []rbacv1.ClusterRole{
{
// a "root" role which can do absolutely anything
ObjectMeta: metav1.ObjectMeta{Name: "cluster-admin"},
Rules: []rbac.PolicyRule{
rbac.NewRule("*").Groups("*").Resources("*").RuleOrDie(),
rbac.NewRule("*").URLs("*").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("*").Groups("*").Resources("*").RuleOrDie(),
rbacv1helpers.NewRule("*").URLs("*").RuleOrDie(),
},
},
{
// a role which provides just enough power to determine if the server is ready and discover API versions for negotiation
ObjectMeta: metav1.ObjectMeta{Name: "system:discovery"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get").URLs(
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get").URLs(
"/healthz", "/version", "/version/",
// remove once swagger 1.2 support is removed
"/swaggerapi", "/swaggerapi/*",
@@ -192,16 +193,16 @@ func ClusterRoles() []rbac.ClusterRole {
{
// a role which provides minimal resource access to allow a "normal" user to learn information about themselves
ObjectMeta: metav1.ObjectMeta{Name: "system:basic-user"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
// TODO add future selfsubjectrulesreview, project request APIs, project listing APIs
rbac.NewRule("create").Groups(authorizationGroup).Resources("selfsubjectaccessreviews", "selfsubjectrulesreviews").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(authorizationGroup).Resources("selfsubjectaccessreviews", "selfsubjectrulesreviews").RuleOrDie(),
},
},
{
// a role for a namespace level admin. It is `edit` plus the power to grant permissions to other users.
ObjectMeta: metav1.ObjectMeta{Name: "admin"},
AggregationRule: &rbac.AggregationRule{
AggregationRule: &rbacv1.AggregationRule{
ClusterRoleSelectors: []metav1.LabelSelector{{MatchLabels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-admin": "true"}}},
},
},
@@ -210,7 +211,7 @@ func ClusterRoles() []rbac.ClusterRole {
// 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{
AggregationRule: &rbacv1.AggregationRule{
ClusterRoleSelectors: []metav1.LabelSelector{{MatchLabels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-edit": "true"}}},
},
},
@@ -218,46 +219,46 @@ func ClusterRoles() []rbac.ClusterRole {
// 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{
AggregationRule: &rbacv1.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{
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",
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule(ReadWrite...).Groups(legacyGroup).Resources("pods", "pods/attach", "pods/proxy", "pods/exec", "pods/portforward").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(legacyGroup).Resources("replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
"services", "services/proxy", "endpoints", "persistentvolumeclaims", "configmaps", "secrets").RuleOrDie(),
rbac.NewRule(Read...).Groups(legacyGroup).Resources("limitranges", "resourcequotas", "bindings", "events",
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("limitranges", "resourcequotas", "bindings", "events",
"pods/status", "resourcequotas/status", "namespaces/status", "replicationcontrollers/status", "pods/log").RuleOrDie(),
// read access to namespaces at the namespace scope means you can read *this* namespace. This can be used as an
// indicator of which namespaces you have access to.
rbac.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
rbac.NewRule("impersonate").Groups(legacyGroup).Resources("serviceaccounts").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
rbacv1helpers.NewRule("impersonate").Groups(legacyGroup).Resources("serviceaccounts").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(appsGroup).Resources(
rbacv1helpers.NewRule(ReadWrite...).Groups(appsGroup).Resources(
"statefulsets", "statefulsets/scale",
"daemonsets",
"deployments", "deployments/scale", "deployments/rollback",
"replicasets", "replicasets/scale").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(batchGroup).Resources("jobs", "cronjobs").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(batchGroup).Resources("jobs", "cronjobs").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(extensionsGroup).Resources("daemonsets",
rbacv1helpers.NewRule(ReadWrite...).Groups(extensionsGroup).Resources("daemonsets",
"deployments", "deployments/scale", "deployments/rollback", "ingresses",
"replicasets", "replicasets/scale", "replicationcontrollers/scale",
"networkpolicies").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(networkingGroup).Resources("networkpolicies").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(networkingGroup).Resources("networkpolicies").RuleOrDie(),
// additional admin powers
rbac.NewRule("create").Groups(authorizationGroup).Resources("localsubjectaccessreviews").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(rbacGroup).Resources("roles", "rolebindings").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(authorizationGroup).Resources("localsubjectaccessreviews").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(rbacGroup).Resources("roles", "rolebindings").RuleOrDie(),
},
},
{
@@ -265,75 +266,75 @@ func ClusterRoles() []rbac.ClusterRole {
// 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: "system:aggregate-to-edit", Labels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-edit": "true"}},
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("replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule(ReadWrite...).Groups(legacyGroup).Resources("pods", "pods/attach", "pods/proxy", "pods/exec", "pods/portforward").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(legacyGroup).Resources("replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
"services", "services/proxy", "endpoints", "persistentvolumeclaims", "configmaps", "secrets").RuleOrDie(),
rbac.NewRule(Read...).Groups(legacyGroup).Resources("limitranges", "resourcequotas", "bindings", "events",
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("limitranges", "resourcequotas", "bindings", "events",
"pods/status", "resourcequotas/status", "namespaces/status", "replicationcontrollers/status", "pods/log").RuleOrDie(),
// read access to namespaces at the namespace scope means you can read *this* namespace. This can be used as an
// indicator of which namespaces you have access to.
rbac.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
rbac.NewRule("impersonate").Groups(legacyGroup).Resources("serviceaccounts").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
rbacv1helpers.NewRule("impersonate").Groups(legacyGroup).Resources("serviceaccounts").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(appsGroup).Resources(
rbacv1helpers.NewRule(ReadWrite...).Groups(appsGroup).Resources(
"statefulsets", "statefulsets/scale",
"daemonsets",
"deployments", "deployments/scale", "deployments/rollback",
"replicasets", "replicasets/scale").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(batchGroup).Resources("jobs", "cronjobs").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(batchGroup).Resources("jobs", "cronjobs").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(extensionsGroup).Resources("daemonsets",
rbacv1helpers.NewRule(ReadWrite...).Groups(extensionsGroup).Resources("daemonsets",
"deployments", "deployments/scale", "deployments/rollback", "ingresses",
"replicasets", "replicasets/scale", "replicationcontrollers/scale",
"networkpolicies").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
rbac.NewRule(ReadWrite...).Groups(networkingGroup).Resources("networkpolicies").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(networkingGroup).Resources("networkpolicies").RuleOrDie(),
},
},
{
// a role for namespace level viewing. It grants Read-only access to non-escalating resources in
// a namespace.
ObjectMeta: metav1.ObjectMeta{Name: "system:aggregate-to-view", Labels: map[string]string{"rbac.authorization.k8s.io/aggregate-to-view": "true"}},
Rules: []rbac.PolicyRule{
rbac.NewRule(Read...).Groups(legacyGroup).Resources("pods", "replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("pods", "replicationcontrollers", "replicationcontrollers/scale", "serviceaccounts",
"services", "endpoints", "persistentvolumeclaims", "configmaps").RuleOrDie(),
rbac.NewRule(Read...).Groups(legacyGroup).Resources("limitranges", "resourcequotas", "bindings", "events",
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("limitranges", "resourcequotas", "bindings", "events",
"pods/status", "resourcequotas/status", "namespaces/status", "replicationcontrollers/status", "pods/log").RuleOrDie(),
// read access to namespaces at the namespace scope means you can read *this* namespace. This can be used as an
// indicator of which namespaces you have access to.
rbac.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("namespaces").RuleOrDie(),
rbac.NewRule(Read...).Groups(appsGroup).Resources(
rbacv1helpers.NewRule(Read...).Groups(appsGroup).Resources(
"statefulsets", "statefulsets/scale",
"daemonsets",
"deployments", "deployments/scale",
"replicasets", "replicasets/scale").RuleOrDie(),
rbac.NewRule(Read...).Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(),
rbac.NewRule(Read...).Groups(batchGroup).Resources("jobs", "cronjobs").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(batchGroup).Resources("jobs", "cronjobs").RuleOrDie(),
rbac.NewRule(Read...).Groups(extensionsGroup).Resources("daemonsets", "deployments", "deployments/scale",
rbacv1helpers.NewRule(Read...).Groups(extensionsGroup).Resources("daemonsets", "deployments", "deployments/scale",
"ingresses", "replicasets", "replicasets/scale", "replicationcontrollers/scale",
"networkpolicies").RuleOrDie(),
rbac.NewRule(Read...).Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
rbac.NewRule(Read...).Groups(networkingGroup).Resources("networkpolicies").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(networkingGroup).Resources("networkpolicies").RuleOrDie(),
},
},
{
// a role to use for heapster's connections back to the API server
ObjectMeta: metav1.ObjectMeta{Name: "system:heapster"},
Rules: []rbac.PolicyRule{
rbac.NewRule(Read...).Groups(legacyGroup).Resources("events", "pods", "nodes", "namespaces").RuleOrDie(),
rbac.NewRule(Read...).Groups(extensionsGroup).Resources("deployments").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("events", "pods", "nodes", "namespaces").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(extensionsGroup).Resources("deployments").RuleOrDie(),
},
},
{
@@ -345,19 +346,19 @@ func ClusterRoles() []rbac.ClusterRole {
// a role to use for node-problem-detector access. It does not get bound to default location since
// deployment locations can reasonably vary.
ObjectMeta: metav1.ObjectMeta{Name: "system:node-problem-detector"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbac.NewRule("patch").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("patch").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(),
eventsRule(),
},
},
{
// a role to use for setting up a proxy
ObjectMeta: metav1.ObjectMeta{Name: "system:node-proxier"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
// Used to build serviceLister
rbac.NewRule("list", "watch").Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(),
rbac.NewRule("get").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(),
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
eventsRule(),
},
@@ -365,98 +366,98 @@ func ClusterRoles() []rbac.ClusterRole {
{
// a role to use for full access to the kubelet API
ObjectMeta: metav1.ObjectMeta{Name: "system:kubelet-api-admin"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
// Allow read-only access to the Node API objects
rbac.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
// Allow all API calls to the nodes
rbac.NewRule("proxy").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbac.NewRule("*").Groups(legacyGroup).Resources("nodes/proxy", "nodes/metrics", "nodes/spec", "nodes/stats", "nodes/log").RuleOrDie(),
rbacv1helpers.NewRule("proxy").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("*").Groups(legacyGroup).Resources("nodes/proxy", "nodes/metrics", "nodes/spec", "nodes/stats", "nodes/log").RuleOrDie(),
},
},
{
// a role to use for bootstrapping a node's client certificates
ObjectMeta: metav1.ObjectMeta{Name: "system:node-bootstrapper"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
// used to create a certificatesigningrequest for a node-specific client certificate, and watch for it to be signed
rbac.NewRule("create", "get", "list", "watch").Groups(certificatesGroup).Resources("certificatesigningrequests").RuleOrDie(),
rbacv1helpers.NewRule("create", "get", "list", "watch").Groups(certificatesGroup).Resources("certificatesigningrequests").RuleOrDie(),
},
},
{
// a role to use for allowing authentication and authorization delegation
ObjectMeta: metav1.ObjectMeta{Name: "system:auth-delegator"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
// These creates are non-mutating
rbac.NewRule("create").Groups(authenticationGroup).Resources("tokenreviews").RuleOrDie(),
rbac.NewRule("create").Groups(authorizationGroup).Resources("subjectaccessreviews").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(authenticationGroup).Resources("tokenreviews").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(authorizationGroup).Resources("subjectaccessreviews").RuleOrDie(),
},
},
{
// a role to use for the API registry, summarization, and proxy handling
ObjectMeta: metav1.ObjectMeta{Name: "system:kube-aggregator"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
// it needs to see all services so that it knows whether the ones it points to exist or not
rbac.NewRule(Read...).Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(),
},
},
{
// a role to use for bootstrapping the kube-controller-manager so it can create the shared informers
// service accounts, and secrets that we need to create separate identities for other controllers
ObjectMeta: metav1.ObjectMeta{Name: "system:kube-controller-manager"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
eventsRule(),
rbac.NewRule("create").Groups(legacyGroup).Resources("endpoints", "secrets", "serviceaccounts").RuleOrDie(),
rbac.NewRule("delete").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
rbac.NewRule("get").Groups(legacyGroup).Resources("endpoints", "namespaces", "secrets", "serviceaccounts").RuleOrDie(),
rbac.NewRule("update").Groups(legacyGroup).Resources("endpoints", "secrets", "serviceaccounts").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("endpoints", "secrets", "serviceaccounts").RuleOrDie(),
rbacv1helpers.NewRule("delete").Groups(legacyGroup).Resources("secrets").RuleOrDie(),
rbacv1helpers.NewRule("get").Groups(legacyGroup).Resources("endpoints", "namespaces", "secrets", "serviceaccounts").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("endpoints", "secrets", "serviceaccounts").RuleOrDie(),
// Needed to check API access. These creates are non-mutating
rbac.NewRule("create").Groups(authenticationGroup).Resources("tokenreviews").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(authenticationGroup).Resources("tokenreviews").RuleOrDie(),
// Needed for all shared informers
rbac.NewRule("list", "watch").Groups("*").Resources("*").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch").Groups("*").Resources("*").RuleOrDie(),
},
},
{
// a role to use for the kube-scheduler
ObjectMeta: metav1.ObjectMeta{Name: "system:kube-scheduler"},
Rules: []rbac.PolicyRule{
Rules: []rbacv1.PolicyRule{
eventsRule(),
// this is for leaderlease access
// TODO: scope this to the kube-system namespace
rbac.NewRule("create").Groups(legacyGroup).Resources("endpoints").RuleOrDie(),
rbac.NewRule("get", "update", "patch", "delete").Groups(legacyGroup).Resources("endpoints").Names("kube-scheduler").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("endpoints").RuleOrDie(),
rbacv1helpers.NewRule("get", "update", "patch", "delete").Groups(legacyGroup).Resources("endpoints").Names("kube-scheduler").RuleOrDie(),
// fundamental resources
rbac.NewRule(Read...).Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbac.NewRule("get", "list", "watch", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbac.NewRule("create").Groups(legacyGroup).Resources("pods/binding", "bindings").RuleOrDie(),
rbac.NewRule("patch", "update").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("pods/binding", "bindings").RuleOrDie(),
rbacv1helpers.NewRule("patch", "update").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
// things that select pods
rbac.NewRule(Read...).Groups(legacyGroup).Resources("services", "replicationcontrollers").RuleOrDie(),
rbac.NewRule(Read...).Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
rbac.NewRule(Read...).Groups(appsGroup).Resources("statefulsets").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("services", "replicationcontrollers").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(appsGroup, extensionsGroup).Resources("replicasets").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(appsGroup).Resources("statefulsets").RuleOrDie(),
// things that pods use or applies to them
rbac.NewRule(Read...).Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
rbac.NewRule(Read...).Groups(legacyGroup).Resources("persistentvolumeclaims", "persistentvolumes").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(legacyGroup).Resources("persistentvolumeclaims", "persistentvolumes").RuleOrDie(),
},
},
{
// a role to use for the kube-dns pod
ObjectMeta: metav1.ObjectMeta{Name: "system:kube-dns"},
Rules: []rbac.PolicyRule{
rbac.NewRule("list", "watch").Groups(legacyGroup).Resources("endpoints", "services").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("list", "watch").Groups(legacyGroup).Resources("endpoints", "services").RuleOrDie(),
},
},
{
// a role for an external/out-of-tree persistent volume provisioner
ObjectMeta: metav1.ObjectMeta{Name: "system:persistent-volume-provisioner"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "create", "delete").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "create", "delete").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
// update is needed in addition to read access for setting lock annotations on PVCs
rbac.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
rbac.NewRule(Read...).Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
// Needed for watching provisioning success and failure events
rbac.NewRule("watch").Groups(legacyGroup).Resources("events").RuleOrDie(),
rbacv1helpers.NewRule("watch").Groups(legacyGroup).Resources("events").RuleOrDie(),
eventsRule(),
},
@@ -464,52 +465,52 @@ func ClusterRoles() []rbac.ClusterRole {
{
// a role for the csi external provisioner
ObjectMeta: metav1.ObjectMeta{Name: "system:csi-external-provisioner"},
Rules: []rbac.PolicyRule{
rbac.NewRule("create", "delete", "list", "watch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
rbac.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
rbac.NewRule("list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
rbac.NewRule("get", "list", "watch", "create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("create", "delete", "list", "watch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(),
rbacv1helpers.NewRule("list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie(),
},
},
{
// a role for the csi external attacher
ObjectMeta: metav1.ObjectMeta{Name: "system:csi-external-attacher"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
rbac.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbac.NewRule("get", "list", "watch", "update", "patch").Groups(storageGroup).Resources("volumeattachments").RuleOrDie(),
rbac.NewRule("get", "list", "watch", "create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(storageGroup).Resources("volumeattachments").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie(),
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: "system:aws-cloud-provider"},
Rules: []rbac.PolicyRule{
rbac.NewRule("get", "patch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "patch").Groups(legacyGroup).Resources("nodes").RuleOrDie(),
eventsRule(),
},
},
{
// a role making the csrapprover controller approve a node client CSR
ObjectMeta: metav1.ObjectMeta{Name: "system:certificates.k8s.io:certificatesigningrequests:nodeclient"},
Rules: []rbac.PolicyRule{
rbac.NewRule("create").Groups(certificatesGroup).Resources("certificatesigningrequests/nodeclient").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("create").Groups(certificatesGroup).Resources("certificatesigningrequests/nodeclient").RuleOrDie(),
},
},
{
// a role making the csrapprover controller approve a node client CSR requested by the node itself
ObjectMeta: metav1.ObjectMeta{Name: "system:certificates.k8s.io:certificatesigningrequests:selfnodeclient"},
Rules: []rbac.PolicyRule{
rbac.NewRule("create").Groups(certificatesGroup).Resources("certificatesigningrequests/selfnodeclient").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule("create").Groups(certificatesGroup).Resources("certificatesigningrequests/selfnodeclient").RuleOrDie(),
},
},
}
if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
roles = append(roles, rbac.ClusterRole{
roles = append(roles, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: "system:volume-scheduler"},
Rules: []rbac.PolicyRule{
rbac.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
rbac.NewRule(Read...).Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
Rules: []rbacv1.PolicyRule{
rbacv1helpers.NewRule(ReadUpdate...).Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("storageclasses").RuleOrDie(),
},
})
}
@@ -521,27 +522,27 @@ func ClusterRoles() []rbac.ClusterRole {
const systemNodeRoleName = "system:node"
// ClusterRoleBindings return default rolebindings to the default roles
func ClusterRoleBindings() []rbac.ClusterRoleBinding {
rolebindings := []rbac.ClusterRoleBinding{
rbac.NewClusterBinding("cluster-admin").Groups(user.SystemPrivilegedGroup).BindingOrDie(),
rbac.NewClusterBinding("system:discovery").Groups(user.AllAuthenticated, user.AllUnauthenticated).BindingOrDie(),
rbac.NewClusterBinding("system:basic-user").Groups(user.AllAuthenticated, user.AllUnauthenticated).BindingOrDie(),
rbac.NewClusterBinding("system:node-proxier").Users(user.KubeProxy).BindingOrDie(),
rbac.NewClusterBinding("system:kube-controller-manager").Users(user.KubeControllerManager).BindingOrDie(),
rbac.NewClusterBinding("system:kube-dns").SAs("kube-system", "kube-dns").BindingOrDie(),
rbac.NewClusterBinding("system:kube-scheduler").Users(user.KubeScheduler).BindingOrDie(),
rbac.NewClusterBinding("system:aws-cloud-provider").SAs("kube-system", "aws-cloud-provider").BindingOrDie(),
func ClusterRoleBindings() []rbacv1.ClusterRoleBinding {
rolebindings := []rbacv1.ClusterRoleBinding{
rbacv1helpers.NewClusterBinding("cluster-admin").Groups(user.SystemPrivilegedGroup).BindingOrDie(),
rbacv1helpers.NewClusterBinding("system:discovery").Groups(user.AllAuthenticated, user.AllUnauthenticated).BindingOrDie(),
rbacv1helpers.NewClusterBinding("system:basic-user").Groups(user.AllAuthenticated, user.AllUnauthenticated).BindingOrDie(),
rbacv1helpers.NewClusterBinding("system:node-proxier").Users(user.KubeProxy).BindingOrDie(),
rbacv1helpers.NewClusterBinding("system:kube-controller-manager").Users(user.KubeControllerManager).BindingOrDie(),
rbacv1helpers.NewClusterBinding("system:kube-dns").SAs("kube-system", "kube-dns").BindingOrDie(),
rbacv1helpers.NewClusterBinding("system:kube-scheduler").Users(user.KubeScheduler).BindingOrDie(),
rbacv1helpers.NewClusterBinding("system:aws-cloud-provider").SAs("kube-system", "aws-cloud-provider").BindingOrDie(),
// This default binding of the system:node role to the system:nodes group is deprecated in 1.7 with the availability of the Node authorizer.
// This leaves the binding, but with an empty set of subjects, so that tightening reconciliation can remove the subject.
{
ObjectMeta: metav1.ObjectMeta{Name: systemNodeRoleName},
RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "ClusterRole", Name: systemNodeRoleName},
RoleRef: rbacv1.RoleRef{APIGroup: rbacv1.GroupName, Kind: "ClusterRole", Name: systemNodeRoleName},
},
}
if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
rolebindings = append(rolebindings, rbac.NewClusterBinding("system:volume-scheduler").Users(user.KubeScheduler).BindingOrDie())
rolebindings = append(rolebindings, rbacv1helpers.NewClusterBinding("system:volume-scheduler").Users(user.KubeScheduler).BindingOrDie())
}
addClusterRoleBindingLabel(rolebindings)

View File

@@ -34,8 +34,8 @@ import (
"k8s.io/kubernetes/pkg/api/legacyscheme"
api "k8s.io/kubernetes/pkg/apis/core"
_ "k8s.io/kubernetes/pkg/apis/core/install"
"k8s.io/kubernetes/pkg/apis/rbac"
_ "k8s.io/kubernetes/pkg/apis/rbac/install"
rbacv1helpers "k8s.io/kubernetes/pkg/apis/rbac/v1"
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
)
@@ -43,12 +43,12 @@ import (
// semanticRoles is a few enumerated roles for which the relationships are well established
// and we want to maintain symmetric roles
type semanticRoles struct {
admin *rbac.ClusterRole
edit *rbac.ClusterRole
view *rbac.ClusterRole
admin *rbacv1.ClusterRole
edit *rbacv1.ClusterRole
view *rbacv1.ClusterRole
}
func getSemanticRoles(roles []rbac.ClusterRole) semanticRoles {
func getSemanticRoles(roles []rbacv1.ClusterRole) semanticRoles {
ret := semanticRoles{}
for i := range roles {
role := roles[i]
@@ -81,10 +81,10 @@ func TestCovers(t *testing.T) {
// additionalAdminPowers is the list of powers that we expect to be different than the editor role.
// one resource per rule to make the "does not already contain" check easy
var additionalAdminPowers = []rbac.PolicyRule{
rbac.NewRule("create").Groups("authorization.k8s.io").Resources("localsubjectaccessreviews").RuleOrDie(),
rbac.NewRule(bootstrappolicy.ReadWrite...).Groups("rbac.authorization.k8s.io").Resources("rolebindings").RuleOrDie(),
rbac.NewRule(bootstrappolicy.ReadWrite...).Groups("rbac.authorization.k8s.io").Resources("roles").RuleOrDie(),
var additionalAdminPowers = []rbacv1.PolicyRule{
rbacv1helpers.NewRule("create").Groups("authorization.k8s.io").Resources("localsubjectaccessreviews").RuleOrDie(),
rbacv1helpers.NewRule(bootstrappolicy.ReadWrite...).Groups("rbac.authorization.k8s.io").Resources("rolebindings").RuleOrDie(),
rbacv1helpers.NewRule(bootstrappolicy.ReadWrite...).Groups("rbac.authorization.k8s.io").Resources("roles").RuleOrDie(),
}
func TestAdminEditRelationship(t *testing.T) {
@@ -92,7 +92,7 @@ func TestAdminEditRelationship(t *testing.T) {
// confirm that the edit role doesn't already have extra powers
for _, rule := range additionalAdminPowers {
if covers, _ := rbacregistryvalidation.Covers(semanticRoles.edit.Rules, []rbac.PolicyRule{rule}); covers {
if covers, _ := rbacregistryvalidation.Covers(semanticRoles.edit.Rules, []rbacv1.PolicyRule{rule}); covers {
t.Errorf("edit has extra powers: %#v", rule)
}
}
@@ -109,19 +109,19 @@ func TestAdminEditRelationship(t *testing.T) {
// viewEscalatingNamespaceResources is the list of rules that would allow privilege escalation attacks based on
// ability to view (GET) them
var viewEscalatingNamespaceResources = []rbac.PolicyRule{
rbac.NewRule(bootstrappolicy.Read...).Groups("").Resources("pods/attach").RuleOrDie(),
rbac.NewRule(bootstrappolicy.Read...).Groups("").Resources("pods/proxy").RuleOrDie(),
rbac.NewRule(bootstrappolicy.Read...).Groups("").Resources("pods/exec").RuleOrDie(),
rbac.NewRule(bootstrappolicy.Read...).Groups("").Resources("pods/portforward").RuleOrDie(),
rbac.NewRule(bootstrappolicy.Read...).Groups("").Resources("secrets").RuleOrDie(),
rbac.NewRule(bootstrappolicy.Read...).Groups("").Resources("services/proxy").RuleOrDie(),
var viewEscalatingNamespaceResources = []rbacv1.PolicyRule{
rbacv1helpers.NewRule(bootstrappolicy.Read...).Groups("").Resources("pods/attach").RuleOrDie(),
rbacv1helpers.NewRule(bootstrappolicy.Read...).Groups("").Resources("pods/proxy").RuleOrDie(),
rbacv1helpers.NewRule(bootstrappolicy.Read...).Groups("").Resources("pods/exec").RuleOrDie(),
rbacv1helpers.NewRule(bootstrappolicy.Read...).Groups("").Resources("pods/portforward").RuleOrDie(),
rbacv1helpers.NewRule(bootstrappolicy.Read...).Groups("").Resources("secrets").RuleOrDie(),
rbacv1helpers.NewRule(bootstrappolicy.Read...).Groups("").Resources("services/proxy").RuleOrDie(),
}
// ungettableResources is the list of rules that don't allow to view (GET) them
// this is purposefully separate list to distinguish from escalating privs
var ungettableResources = []rbac.PolicyRule{
rbac.NewRule(bootstrappolicy.Read...).Groups("apps", "extensions").Resources("deployments/rollback").RuleOrDie(),
var ungettableResources = []rbacv1.PolicyRule{
rbacv1helpers.NewRule(bootstrappolicy.Read...).Groups("apps", "extensions").Resources("deployments/rollback").RuleOrDie(),
}
func TestEditViewRelationship(t *testing.T) {
@@ -143,7 +143,7 @@ func TestEditViewRelationship(t *testing.T) {
// confirm that the view role doesn't already have extra powers
for _, rule := range viewEscalatingNamespaceResources {
if covers, _ := rbacregistryvalidation.Covers(semanticRoles.view.Rules, []rbac.PolicyRule{rule}); covers {
if covers, _ := rbacregistryvalidation.Covers(semanticRoles.view.Rules, []rbacv1.PolicyRule{rule}); covers {
t.Errorf("view has extra powers: %#v", rule)
}
}
@@ -151,7 +151,7 @@ func TestEditViewRelationship(t *testing.T) {
// confirm that the view role doesn't have ungettable resources
for _, rule := range ungettableResources {
if covers, _ := rbacregistryvalidation.Covers(semanticRoles.view.Rules, []rbac.PolicyRule{rule}); covers {
if covers, _ := rbacregistryvalidation.Covers(semanticRoles.view.Rules, []rbacv1.PolicyRule{rule}); covers {
t.Errorf("view has ungettable resource: %#v", rule)
}
}

View File

@@ -18,18 +18,18 @@ limitations under the License.
package rbac
import (
"bytes"
"fmt"
"github.com/golang/glog"
"bytes"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/labels"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/kubernetes/pkg/apis/rbac"
rbaclisters "k8s.io/kubernetes/pkg/client/listers/rbac/internalversion"
rbaclisters "k8s.io/client-go/listers/rbac/v1"
rbacv1helpers "k8s.io/kubernetes/pkg/apis/rbac/v1"
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
)
@@ -38,12 +38,12 @@ type RequestToRuleMapper interface {
// Any rule returned is still valid, since rules are deny by default. If you can pass with the rules
// supplied, you do not have to fail the request. If you cannot, you should indicate the error along
// with your denial.
RulesFor(subject user.Info, namespace string) ([]rbac.PolicyRule, error)
RulesFor(subject user.Info, namespace string) ([]rbacv1.PolicyRule, error)
// VisitRulesFor invokes visitor() with each rule that applies to a given user in a given namespace,
// and each error encountered resolving those rules. Rule may be nil if err is non-nil.
// If visitor() returns false, visiting is short-circuited.
VisitRulesFor(user user.Info, namespace string, visitor func(source fmt.Stringer, rule *rbac.PolicyRule, err error) bool)
VisitRulesFor(user user.Info, namespace string, visitor func(source fmt.Stringer, rule *rbacv1.PolicyRule, err error) bool)
}
type RBACAuthorizer struct {
@@ -59,7 +59,7 @@ type authorizingVisitor struct {
errors []error
}
func (v *authorizingVisitor) visit(source fmt.Stringer, rule *rbac.PolicyRule, err error) bool {
func (v *authorizingVisitor) visit(source fmt.Stringer, rule *rbacv1.PolicyRule, err error) bool {
if rule != nil && RuleAllows(v.requestAttributes, rule) {
v.allowed = true
v.reason = fmt.Sprintf("RBAC: allowed by %s", source.String())
@@ -164,7 +164,7 @@ func New(roles rbacregistryvalidation.RoleGetter, roleBindings rbacregistryvalid
return authorizer
}
func RulesAllow(requestAttributes authorizer.Attributes, rules ...rbac.PolicyRule) bool {
func RulesAllow(requestAttributes authorizer.Attributes, rules ...rbacv1.PolicyRule) bool {
for i := range rules {
if RuleAllows(requestAttributes, &rules[i]) {
return true
@@ -174,28 +174,28 @@ func RulesAllow(requestAttributes authorizer.Attributes, rules ...rbac.PolicyRul
return false
}
func RuleAllows(requestAttributes authorizer.Attributes, rule *rbac.PolicyRule) bool {
func RuleAllows(requestAttributes authorizer.Attributes, rule *rbacv1.PolicyRule) bool {
if requestAttributes.IsResourceRequest() {
combinedResource := requestAttributes.GetResource()
if len(requestAttributes.GetSubresource()) > 0 {
combinedResource = requestAttributes.GetResource() + "/" + requestAttributes.GetSubresource()
}
return rbac.VerbMatches(rule, requestAttributes.GetVerb()) &&
rbac.APIGroupMatches(rule, requestAttributes.GetAPIGroup()) &&
rbac.ResourceMatches(rule, combinedResource, requestAttributes.GetSubresource()) &&
rbac.ResourceNameMatches(rule, requestAttributes.GetName())
return rbacv1helpers.VerbMatches(rule, requestAttributes.GetVerb()) &&
rbacv1helpers.APIGroupMatches(rule, requestAttributes.GetAPIGroup()) &&
rbacv1helpers.ResourceMatches(rule, combinedResource, requestAttributes.GetSubresource()) &&
rbacv1helpers.ResourceNameMatches(rule, requestAttributes.GetName())
}
return rbac.VerbMatches(rule, requestAttributes.GetVerb()) &&
rbac.NonResourceURLMatches(rule, requestAttributes.GetPath())
return rbacv1helpers.VerbMatches(rule, requestAttributes.GetVerb()) &&
rbacv1helpers.NonResourceURLMatches(rule, requestAttributes.GetPath())
}
type RoleGetter struct {
Lister rbaclisters.RoleLister
}
func (g *RoleGetter) GetRole(namespace, name string) (*rbac.Role, error) {
func (g *RoleGetter) GetRole(namespace, name string) (*rbacv1.Role, error) {
return g.Lister.Roles(namespace).Get(name)
}
@@ -203,7 +203,7 @@ type RoleBindingLister struct {
Lister rbaclisters.RoleBindingLister
}
func (l *RoleBindingLister) ListRoleBindings(namespace string) ([]*rbac.RoleBinding, error) {
func (l *RoleBindingLister) ListRoleBindings(namespace string) ([]*rbacv1.RoleBinding, error) {
return l.Lister.RoleBindings(namespace).List(labels.Everything())
}
@@ -211,7 +211,7 @@ type ClusterRoleGetter struct {
Lister rbaclisters.ClusterRoleLister
}
func (g *ClusterRoleGetter) GetClusterRole(name string) (*rbac.ClusterRole, error) {
func (g *ClusterRoleGetter) GetClusterRole(name string) (*rbacv1.ClusterRole, error) {
return g.Lister.Get(name)
}
@@ -219,6 +219,6 @@ type ClusterRoleBindingLister struct {
Lister rbaclisters.ClusterRoleBindingLister
}
func (l *ClusterRoleBindingLister) ListClusterRoleBindings() ([]*rbac.ClusterRoleBinding, error) {
func (l *ClusterRoleBindingLister) ListClusterRoleBindings() ([]*rbacv1.ClusterRoleBinding, error) {
return l.Lister.List(labels.Everything())
}

View File

@@ -21,16 +21,17 @@ import (
"strings"
"testing"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/kubernetes/pkg/apis/rbac"
rbacv1helpers "k8s.io/kubernetes/pkg/apis/rbac/v1"
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
)
func newRule(verbs, apiGroups, resources, nonResourceURLs string) rbac.PolicyRule {
return rbac.PolicyRule{
func newRule(verbs, apiGroups, resources, nonResourceURLs string) rbacv1.PolicyRule {
return rbacv1.PolicyRule{
Verbs: strings.Split(verbs, ","),
APIGroups: strings.Split(apiGroups, ","),
Resources: strings.Split(resources, ","),
@@ -38,12 +39,12 @@ func newRule(verbs, apiGroups, resources, nonResourceURLs string) rbac.PolicyRul
}
}
func newRole(name, namespace string, rules ...rbac.PolicyRule) *rbac.Role {
return &rbac.Role{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name}, Rules: rules}
func newRole(name, namespace string, rules ...rbacv1.PolicyRule) *rbacv1.Role {
return &rbacv1.Role{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name}, Rules: rules}
}
func newClusterRole(name string, rules ...rbac.PolicyRule) *rbac.ClusterRole {
return &rbac.ClusterRole{ObjectMeta: metav1.ObjectMeta{Name: name}, Rules: rules}
func newClusterRole(name string, rules ...rbacv1.PolicyRule) *rbacv1.ClusterRole {
return &rbacv1.ClusterRole{ObjectMeta: metav1.ObjectMeta{Name: name}, Rules: rules}
}
const (
@@ -51,26 +52,26 @@ const (
bindToClusterRole uint16 = 0x1
)
func newClusterRoleBinding(roleName string, subjects ...string) *rbac.ClusterRoleBinding {
r := &rbac.ClusterRoleBinding{
func newClusterRoleBinding(roleName string, subjects ...string) *rbacv1.ClusterRoleBinding {
r := &rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{},
RoleRef: rbac.RoleRef{
APIGroup: rbac.GroupName,
RoleRef: rbacv1.RoleRef{
APIGroup: rbacv1.GroupName,
Kind: "ClusterRole", // ClusterRoleBindings can only refer to ClusterRole
Name: roleName,
},
}
r.Subjects = make([]rbac.Subject, len(subjects))
r.Subjects = make([]rbacv1.Subject, len(subjects))
for i, subject := range subjects {
split := strings.SplitN(subject, ":", 2)
r.Subjects[i].Kind, r.Subjects[i].Name = split[0], split[1]
switch r.Subjects[i].Kind {
case rbac.ServiceAccountKind:
case rbacv1.ServiceAccountKind:
r.Subjects[i].APIGroup = ""
case rbac.UserKind, rbac.GroupKind:
r.Subjects[i].APIGroup = rbac.GroupName
case rbacv1.UserKind, rbacv1.GroupKind:
r.Subjects[i].APIGroup = rbacv1.GroupName
default:
panic(fmt.Errorf("invalid kind %s", r.Subjects[i].Kind))
}
@@ -78,26 +79,26 @@ func newClusterRoleBinding(roleName string, subjects ...string) *rbac.ClusterRol
return r
}
func newRoleBinding(namespace, roleName string, bindType uint16, subjects ...string) *rbac.RoleBinding {
r := &rbac.RoleBinding{ObjectMeta: metav1.ObjectMeta{Namespace: namespace}}
func newRoleBinding(namespace, roleName string, bindType uint16, subjects ...string) *rbacv1.RoleBinding {
r := &rbacv1.RoleBinding{ObjectMeta: metav1.ObjectMeta{Namespace: namespace}}
switch bindType {
case bindToRole:
r.RoleRef = rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "Role", Name: roleName}
r.RoleRef = rbacv1.RoleRef{APIGroup: rbacv1.GroupName, Kind: "Role", Name: roleName}
case bindToClusterRole:
r.RoleRef = rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "ClusterRole", Name: roleName}
r.RoleRef = rbacv1.RoleRef{APIGroup: rbacv1.GroupName, Kind: "ClusterRole", Name: roleName}
}
r.Subjects = make([]rbac.Subject, len(subjects))
r.Subjects = make([]rbacv1.Subject, len(subjects))
for i, subject := range subjects {
split := strings.SplitN(subject, ":", 2)
r.Subjects[i].Kind, r.Subjects[i].Name = split[0], split[1]
switch r.Subjects[i].Kind {
case rbac.ServiceAccountKind:
case rbacv1.ServiceAccountKind:
r.Subjects[i].APIGroup = ""
case rbac.UserKind, rbac.GroupKind:
r.Subjects[i].APIGroup = rbac.GroupName
case rbacv1.UserKind, rbacv1.GroupKind:
r.Subjects[i].APIGroup = rbacv1.GroupName
default:
panic(fmt.Errorf("invalid kind %s", r.Subjects[i].Kind))
}
@@ -136,19 +137,19 @@ func (d *defaultAttributes) GetPath() string { return "" }
func TestAuthorizer(t *testing.T) {
tests := []struct {
roles []*rbac.Role
roleBindings []*rbac.RoleBinding
clusterRoles []*rbac.ClusterRole
clusterRoleBindings []*rbac.ClusterRoleBinding
roles []*rbacv1.Role
roleBindings []*rbacv1.RoleBinding
clusterRoles []*rbacv1.ClusterRole
clusterRoleBindings []*rbacv1.ClusterRoleBinding
shouldPass []authorizer.Attributes
shouldFail []authorizer.Attributes
}{
{
clusterRoles: []*rbac.ClusterRole{
clusterRoles: []*rbacv1.ClusterRole{
newClusterRole("admin", newRule("*", "*", "*", "*")),
},
roleBindings: []*rbac.RoleBinding{
roleBindings: []*rbacv1.RoleBinding{
newRoleBinding("ns1", "admin", bindToClusterRole, "User:admin", "Group:admins"),
},
shouldPass: []authorizer.Attributes{
@@ -167,12 +168,12 @@ func TestAuthorizer(t *testing.T) {
},
{
// Non-resource-url tests
clusterRoles: []*rbac.ClusterRole{
clusterRoles: []*rbacv1.ClusterRole{
newClusterRole("non-resource-url-getter", newRule("get", "", "", "/apis")),
newClusterRole("non-resource-url", newRule("*", "", "", "/apis")),
newClusterRole("non-resource-url-prefix", newRule("get", "", "", "/apis/*")),
},
clusterRoleBindings: []*rbac.ClusterRoleBinding{
clusterRoleBindings: []*rbacv1.ClusterRoleBinding{
newClusterRoleBinding("non-resource-url-getter", "User:foo", "Group:bar"),
newClusterRoleBinding("non-resource-url", "User:admin", "Group:admin"),
newClusterRoleBinding("non-resource-url-prefix", "User:prefixed", "Group:prefixed"),
@@ -208,10 +209,10 @@ func TestAuthorizer(t *testing.T) {
},
{
// test subresource resolution
clusterRoles: []*rbac.ClusterRole{
clusterRoles: []*rbacv1.ClusterRole{
newClusterRole("admin", newRule("*", "*", "pods", "*")),
},
roleBindings: []*rbac.RoleBinding{
roleBindings: []*rbacv1.RoleBinding{
newRoleBinding("ns1", "admin", bindToClusterRole, "User:admin", "Group:admins"),
},
shouldPass: []authorizer.Attributes{
@@ -223,13 +224,13 @@ func TestAuthorizer(t *testing.T) {
},
{
// test subresource resolution
clusterRoles: []*rbac.ClusterRole{
clusterRoles: []*rbacv1.ClusterRole{
newClusterRole("admin",
newRule("*", "*", "pods/status", "*"),
newRule("*", "*", "*/scale", "*"),
),
},
roleBindings: []*rbac.RoleBinding{
roleBindings: []*rbacv1.RoleBinding{
newRoleBinding("ns1", "admin", bindToClusterRole, "User:admin", "Group:admins"),
},
shouldPass: []authorizer.Attributes{
@@ -263,13 +264,13 @@ func TestAuthorizer(t *testing.T) {
func TestRuleMatches(t *testing.T) {
tests := []struct {
name string
rule rbac.PolicyRule
rule rbacv1.PolicyRule
requestsToExpected map[authorizer.AttributesRecord]bool
}{
{
name: "star verb, exact match other",
rule: rbac.NewRule("*").Groups("group1").Resources("resource1").RuleOrDie(),
rule: rbacv1helpers.NewRule("*").Groups("group1").Resources("resource1").RuleOrDie(),
requestsToExpected: map[authorizer.AttributesRecord]bool{
resourceRequest("verb1").Group("group1").Resource("resource1").New(): true,
resourceRequest("verb1").Group("group2").Resource("resource1").New(): false,
@@ -283,7 +284,7 @@ func TestRuleMatches(t *testing.T) {
},
{
name: "star group, exact match other",
rule: rbac.NewRule("verb1").Groups("*").Resources("resource1").RuleOrDie(),
rule: rbacv1helpers.NewRule("verb1").Groups("*").Resources("resource1").RuleOrDie(),
requestsToExpected: map[authorizer.AttributesRecord]bool{
resourceRequest("verb1").Group("group1").Resource("resource1").New(): true,
resourceRequest("verb1").Group("group2").Resource("resource1").New(): true,
@@ -297,7 +298,7 @@ func TestRuleMatches(t *testing.T) {
},
{
name: "star resource, exact match other",
rule: rbac.NewRule("verb1").Groups("group1").Resources("*").RuleOrDie(),
rule: rbacv1helpers.NewRule("verb1").Groups("group1").Resources("*").RuleOrDie(),
requestsToExpected: map[authorizer.AttributesRecord]bool{
resourceRequest("verb1").Group("group1").Resource("resource1").New(): true,
resourceRequest("verb1").Group("group2").Resource("resource1").New(): false,
@@ -311,7 +312,7 @@ func TestRuleMatches(t *testing.T) {
},
{
name: "tuple expansion",
rule: rbac.NewRule("verb1", "verb2").Groups("group1", "group2").Resources("resource1", "resource2").RuleOrDie(),
rule: rbacv1helpers.NewRule("verb1", "verb2").Groups("group1", "group2").Resources("resource1", "resource2").RuleOrDie(),
requestsToExpected: map[authorizer.AttributesRecord]bool{
resourceRequest("verb1").Group("group1").Resource("resource1").New(): true,
resourceRequest("verb1").Group("group2").Resource("resource1").New(): true,
@@ -325,7 +326,7 @@ func TestRuleMatches(t *testing.T) {
},
{
name: "subresource expansion",
rule: rbac.NewRule("*").Groups("*").Resources("resource1/subresource1").RuleOrDie(),
rule: rbacv1helpers.NewRule("*").Groups("*").Resources("resource1/subresource1").RuleOrDie(),
requestsToExpected: map[authorizer.AttributesRecord]bool{
resourceRequest("verb1").Group("group1").Resource("resource1").Subresource("subresource1").New(): true,
resourceRequest("verb1").Group("group2").Resource("resource1").Subresource("subresource2").New(): false,
@@ -339,7 +340,7 @@ func TestRuleMatches(t *testing.T) {
},
{
name: "star nonresource, exact match other",
rule: rbac.NewRule("verb1").URLs("*").RuleOrDie(),
rule: rbacv1helpers.NewRule("verb1").URLs("*").RuleOrDie(),
requestsToExpected: map[authorizer.AttributesRecord]bool{
nonresourceRequest("verb1").URL("/foo").New(): true,
nonresourceRequest("verb1").URL("/foo/bar").New(): true,
@@ -355,7 +356,7 @@ func TestRuleMatches(t *testing.T) {
},
{
name: "star nonresource subpath",
rule: rbac.NewRule("verb1").URLs("/foo/*").RuleOrDie(),
rule: rbacv1helpers.NewRule("verb1").URLs("/foo/*").RuleOrDie(),
requestsToExpected: map[authorizer.AttributesRecord]bool{
nonresourceRequest("verb1").URL("/foo").New(): false,
nonresourceRequest("verb1").URL("/foo/bar").New(): true,
@@ -371,7 +372,7 @@ func TestRuleMatches(t *testing.T) {
},
{
name: "star verb, exact nonresource",
rule: rbac.NewRule("*").URLs("/foo", "/foo/bar/one").RuleOrDie(),
rule: rbacv1helpers.NewRule("*").URLs("/foo", "/foo/bar/one").RuleOrDie(),
requestsToExpected: map[authorizer.AttributesRecord]bool{
nonresourceRequest("verb1").URL("/foo").New(): true,
nonresourceRequest("verb1").URL("/foo/bar").New(): false,
@@ -441,19 +442,19 @@ func (r *requestAttributeBuilder) New() authorizer.AttributesRecord {
}
func BenchmarkAuthorize(b *testing.B) {
bootstrapRoles := []rbac.ClusterRole{}
bootstrapRoles := []rbacv1.ClusterRole{}
bootstrapRoles = append(bootstrapRoles, bootstrappolicy.ControllerRoles()...)
bootstrapRoles = append(bootstrapRoles, bootstrappolicy.ClusterRoles()...)
bootstrapBindings := []rbac.ClusterRoleBinding{}
bootstrapBindings := []rbacv1.ClusterRoleBinding{}
bootstrapBindings = append(bootstrapBindings, bootstrappolicy.ClusterRoleBindings()...)
bootstrapBindings = append(bootstrapBindings, bootstrappolicy.ControllerRoleBindings()...)
clusterRoles := []*rbac.ClusterRole{}
clusterRoles := []*rbacv1.ClusterRole{}
for i := range bootstrapRoles {
clusterRoles = append(clusterRoles, &bootstrapRoles[i])
}
clusterRoleBindings := []*rbac.ClusterRoleBinding{}
clusterRoleBindings := []*rbacv1.ClusterRoleBinding{}
for i := range bootstrapBindings {
clusterRoleBindings = append(clusterRoleBindings, &bootstrapBindings[i])
}

View File

@@ -18,21 +18,21 @@ limitations under the License.
package rbac
import (
rbacv1 "k8s.io/api/rbac/v1"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/kubernetes/pkg/apis/rbac"
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
)
type RoleToRuleMapper interface {
// GetRoleReferenceRules attempts to resolve the role reference of a RoleBinding or ClusterRoleBinding. The passed namespace should be the namespace
// of the role binding, the empty string if a cluster role binding.
GetRoleReferenceRules(roleRef rbac.RoleRef, namespace string) ([]rbac.PolicyRule, error)
GetRoleReferenceRules(roleRef rbacv1.RoleRef, namespace string) ([]rbacv1.PolicyRule, error)
}
type SubjectLocator interface {
AllowedSubjects(attributes authorizer.Attributes) ([]rbac.Subject, error)
AllowedSubjects(attributes authorizer.Attributes) ([]rbacv1.Subject, error)
}
var _ = SubjectLocator(&SubjectAccessEvaluator{})
@@ -59,10 +59,10 @@ func NewSubjectAccessEvaluator(roles rbacregistryvalidation.RoleGetter, roleBind
// AllowedSubjects returns the subjects that can perform an action and any errors encountered while computing the list.
// It is possible to have both subjects and errors returned if some rolebindings couldn't be resolved, but others could be.
func (r *SubjectAccessEvaluator) AllowedSubjects(requestAttributes authorizer.Attributes) ([]rbac.Subject, error) {
subjects := []rbac.Subject{{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup}}
func (r *SubjectAccessEvaluator) AllowedSubjects(requestAttributes authorizer.Attributes) ([]rbacv1.Subject, error) {
subjects := []rbacv1.Subject{{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: user.SystemPrivilegedGroup}}
if len(r.superUser) > 0 {
subjects = append(subjects, rbac.Subject{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: r.superUser})
subjects = append(subjects, rbacv1.Subject{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: r.superUser})
}
errorlist := []error{}
@@ -104,7 +104,7 @@ func (r *SubjectAccessEvaluator) AllowedSubjects(requestAttributes authorizer.At
}
}
dedupedSubjects := []rbac.Subject{}
dedupedSubjects := []rbacv1.Subject{}
for _, subject := range subjects {
found := false
for _, curr := range dedupedSubjects {

View File

@@ -20,24 +20,24 @@ import (
"reflect"
"testing"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/kubernetes/pkg/apis/rbac"
rbacregistryvalidation "k8s.io/kubernetes/pkg/registry/rbac/validation"
)
func TestSubjectLocator(t *testing.T) {
type actionToSubjects struct {
action authorizer.Attributes
subjects []rbac.Subject
subjects []rbacv1.Subject
}
tests := []struct {
name string
roles []*rbac.Role
roleBindings []*rbac.RoleBinding
clusterRoles []*rbac.ClusterRole
clusterRoleBindings []*rbac.ClusterRoleBinding
roles []*rbacv1.Role
roleBindings []*rbacv1.RoleBinding
clusterRoles []*rbacv1.ClusterRole
clusterRoleBindings []*rbacv1.ClusterRoleBinding
superUser string
@@ -45,42 +45,42 @@ func TestSubjectLocator(t *testing.T) {
}{
{
name: "no super user, star matches star",
clusterRoles: []*rbac.ClusterRole{
clusterRoles: []*rbacv1.ClusterRole{
newClusterRole("admin", newRule("*", "*", "*", "*")),
},
clusterRoleBindings: []*rbac.ClusterRoleBinding{
clusterRoleBindings: []*rbacv1.ClusterRoleBinding{
newClusterRoleBinding("admin", "User:super-admin", "Group:super-admins"),
},
roleBindings: []*rbac.RoleBinding{
roleBindings: []*rbacv1.RoleBinding{
newRoleBinding("ns1", "admin", bindToClusterRole, "User:admin", "Group:admins"),
},
actionsToSubjects: []actionToSubjects{
{
&defaultAttributes{"", "", "get", "Pods", "", "ns1", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "admins"},
[]rbacv1.Subject{
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: "super-admin"},
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: "super-admins"},
{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: "admin"},
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: "admins"},
},
},
{
// cluster role matches star in namespace
&defaultAttributes{"", "", "*", "Pods", "", "*", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
[]rbacv1.Subject{
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: "super-admin"},
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: "super-admins"},
},
},
{
// empty ns
&defaultAttributes{"", "", "*", "Pods", "", "", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
[]rbacv1.Subject{
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: "super-admin"},
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: "super-admins"},
},
},
},
@@ -88,48 +88,48 @@ func TestSubjectLocator(t *testing.T) {
{
name: "super user, local roles work",
superUser: "foo",
clusterRoles: []*rbac.ClusterRole{
clusterRoles: []*rbacv1.ClusterRole{
newClusterRole("admin", newRule("*", "*", "*", "*")),
},
clusterRoleBindings: []*rbac.ClusterRoleBinding{
clusterRoleBindings: []*rbacv1.ClusterRoleBinding{
newClusterRoleBinding("admin", "User:super-admin", "Group:super-admins"),
},
roles: []*rbac.Role{
roles: []*rbacv1.Role{
newRole("admin", "ns1", newRule("get", "*", "Pods", "*")),
},
roleBindings: []*rbac.RoleBinding{
roleBindings: []*rbacv1.RoleBinding{
newRoleBinding("ns1", "admin", bindToRole, "User:admin", "Group:admins"),
},
actionsToSubjects: []actionToSubjects{
{
&defaultAttributes{"", "", "get", "Pods", "", "ns1", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "foo"},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "admins"},
[]rbacv1.Subject{
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: "foo"},
{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: "super-admin"},
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: "super-admins"},
{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: "admin"},
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: "admins"},
},
},
{
// verb matchies correctly
&defaultAttributes{"", "", "create", "Pods", "", "ns1", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "foo"},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
[]rbacv1.Subject{
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: "foo"},
{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: "super-admin"},
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: "super-admins"},
},
},
{
// binding only works in correct ns
&defaultAttributes{"", "", "get", "Pods", "", "ns2", ""},
[]rbac.Subject{
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "foo"},
{Kind: rbac.UserKind, APIGroup: rbac.GroupName, Name: "super-admin"},
{Kind: rbac.GroupKind, APIGroup: rbac.GroupName, Name: "super-admins"},
[]rbacv1.Subject{
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: user.SystemPrivilegedGroup},
{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: "foo"},
{Kind: rbacv1.UserKind, APIGroup: rbacv1.GroupName, Name: "super-admin"},
{Kind: rbacv1.GroupKind, APIGroup: rbacv1.GroupName, Name: "super-admins"},
},
},
},