Skip to content

Commit 1998308

Browse files
committed
Bootstrap Kube namespaced roles and bindings
This change brings in the upstream namespaced roles that are used by controllers. These will never conflict with the openshift ones since they are required to be in namespaces prefixed with "kube-". Signed-off-by: Monis Khan <[email protected]>
1 parent 42d6825 commit 1998308

File tree

8 files changed

+271
-90
lines changed

8 files changed

+271
-90
lines changed

Diff for: pkg/authorization/apis/authorization/rbacconversion/conversion.go

+6
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ func Convert_authorization_ClusterRole_To_rbac_ClusterRole(in *authorizationapi.
4747

4848
func Convert_authorization_Role_To_rbac_Role(in *authorizationapi.Role, out *rbac.Role, _ conversion.Scope) error {
4949
out.ObjectMeta = in.ObjectMeta
50+
out.Annotations = convert_authorization_Annotations_To_rbac_Annotations(in.Annotations)
5051
out.Rules = convert_api_PolicyRules_To_rbac_PolicyRules(in.Rules)
5152
return nil
5253
}
@@ -61,6 +62,7 @@ func Convert_authorization_ClusterRoleBinding_To_rbac_ClusterRoleBinding(in *aut
6162
}
6263
out.RoleRef = convert_api_RoleRef_To_rbac_RoleRef(&in.RoleRef)
6364
out.ObjectMeta = in.ObjectMeta
65+
out.Annotations = convert_authorization_Annotations_To_rbac_Annotations(in.Annotations)
6466
return nil
6567
}
6668

@@ -74,6 +76,7 @@ func Convert_authorization_RoleBinding_To_rbac_RoleBinding(in *authorizationapi.
7476
}
7577
out.RoleRef = convert_api_RoleRef_To_rbac_RoleRef(&in.RoleRef)
7678
out.ObjectMeta = in.ObjectMeta
79+
out.Annotations = convert_authorization_Annotations_To_rbac_Annotations(in.Annotations)
7780
return nil
7881
}
7982

@@ -172,6 +175,7 @@ func Convert_rbac_ClusterRole_To_authorization_ClusterRole(in *rbac.ClusterRole,
172175

173176
func Convert_rbac_Role_To_authorization_Role(in *rbac.Role, out *authorizationapi.Role, _ conversion.Scope) error {
174177
out.ObjectMeta = in.ObjectMeta
178+
out.Annotations = convert_rbac_Annotations_To_authorization_Annotations(in.Annotations)
175179
out.Rules = Convert_rbac_PolicyRules_To_authorization_PolicyRules(in.Rules)
176180
return nil
177181
}
@@ -185,6 +189,7 @@ func Convert_rbac_ClusterRoleBinding_To_authorization_ClusterRoleBinding(in *rba
185189
return err
186190
}
187191
out.ObjectMeta = in.ObjectMeta
192+
out.Annotations = convert_rbac_Annotations_To_authorization_Annotations(in.Annotations)
188193
return nil
189194
}
190195

@@ -197,6 +202,7 @@ func Convert_rbac_RoleBinding_To_authorization_RoleBinding(in *rbac.RoleBinding,
197202
return err
198203
}
199204
out.ObjectMeta = in.ObjectMeta
205+
out.Annotations = convert_rbac_Annotations_To_authorization_Annotations(in.Annotations)
200206
return nil
201207
}
202208

Diff for: pkg/cmd/server/admin/create_bootstrappolicy_file.go

+60-24
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import (
1010

1111
"github.com/spf13/cobra"
1212

13+
"k8s.io/apimachinery/pkg/util/sets"
1314
kapi "k8s.io/kubernetes/pkg/api"
15+
"k8s.io/kubernetes/pkg/apis/rbac"
1416
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
1517
kprinters "k8s.io/kubernetes/pkg/printers"
1618

@@ -53,6 +55,7 @@ func NewCommandCreateBootstrapPolicyFile(commandName string, fullName string, ou
5355

5456
flags.StringVar(&options.File, "filename", DefaultPolicyFile, "The policy template file that will be written with roles and bindings.")
5557
flags.StringVar(&options.OpenShiftSharedResourcesNamespace, "openshift-namespace", "openshift", "Namespace for shared resources.")
58+
flags.MarkDeprecated("openshift-namespace", "this field is no longer supported and using it can lead to undefined behavior")
5659

5760
// autocompletion hints
5861
cmd.MarkFlagFilename("filename")
@@ -80,11 +83,11 @@ func (o CreateBootstrapPolicyFileOptions) CreateBootstrapPolicyFile() error {
8083
}
8184

8285
policyTemplate := &templateapi.Template{}
86+
policy := bootstrappolicy.Policy()
8387

84-
clusterRoles := bootstrappolicy.GetBootstrapClusterRoles()
85-
for i := range clusterRoles {
88+
for i := range policy.ClusterRoles {
8689
originObject := &authorizationapi.ClusterRole{}
87-
if err := kapi.Scheme.Convert(&clusterRoles[i], originObject, nil); err != nil {
90+
if err := kapi.Scheme.Convert(&policy.ClusterRoles[i], originObject, nil); err != nil {
8891
return err
8992
}
9093
versionedObject, err := kapi.Scheme.ConvertToVersion(originObject, latest.Version)
@@ -94,10 +97,9 @@ func (o CreateBootstrapPolicyFileOptions) CreateBootstrapPolicyFile() error {
9497
policyTemplate.Objects = append(policyTemplate.Objects, versionedObject)
9598
}
9699

97-
clusterRoleBindings := bootstrappolicy.GetBootstrapClusterRoleBindings()
98-
for i := range clusterRoleBindings {
100+
for i := range policy.ClusterRoleBindings {
99101
originObject := &authorizationapi.ClusterRoleBinding{}
100-
if err := kapi.Scheme.Convert(&clusterRoleBindings[i], originObject, nil); err != nil {
102+
if err := kapi.Scheme.Convert(&policy.ClusterRoleBindings[i], originObject, nil); err != nil {
101103
return err
102104
}
103105
versionedObject, err := kapi.Scheme.ConvertToVersion(originObject, latest.Version)
@@ -107,30 +109,64 @@ func (o CreateBootstrapPolicyFileOptions) CreateBootstrapPolicyFile() error {
107109
policyTemplate.Objects = append(policyTemplate.Objects, versionedObject)
108110
}
109111

110-
openshiftRoles := bootstrappolicy.GetBootstrapOpenshiftRoles(o.OpenShiftSharedResourcesNamespace)
111-
for i := range openshiftRoles {
112-
originObject := &authorizationapi.Role{}
113-
if err := kapi.Scheme.Convert(&openshiftRoles[i], originObject, nil); err != nil {
114-
return err
112+
openshiftRoles := map[string][]rbac.Role{}
113+
for namespace, roles := range policy.Roles {
114+
if namespace == bootstrappolicy.DefaultOpenShiftSharedResourcesNamespace {
115+
r := make([]rbac.Role, len(roles))
116+
for i := range roles {
117+
r[i] = roles[i]
118+
r[i].Namespace = o.OpenShiftSharedResourcesNamespace
119+
}
120+
openshiftRoles[o.OpenShiftSharedResourcesNamespace] = r
121+
} else {
122+
openshiftRoles[namespace] = roles
115123
}
116-
versionedObject, err := kapi.Scheme.ConvertToVersion(originObject, latest.Version)
117-
if err != nil {
118-
return err
124+
}
125+
126+
// iterate in a defined order
127+
for _, namespace := range sets.StringKeySet(openshiftRoles).List() {
128+
roles := openshiftRoles[namespace]
129+
for i := range roles {
130+
originObject := &authorizationapi.Role{}
131+
if err := kapi.Scheme.Convert(&roles[i], originObject, nil); err != nil {
132+
return err
133+
}
134+
versionedObject, err := kapi.Scheme.ConvertToVersion(originObject, latest.Version)
135+
if err != nil {
136+
return err
137+
}
138+
policyTemplate.Objects = append(policyTemplate.Objects, versionedObject)
119139
}
120-
policyTemplate.Objects = append(policyTemplate.Objects, versionedObject)
121140
}
122141

123-
openshiftRoleBindings := bootstrappolicy.GetBootstrapOpenshiftRoleBindings(o.OpenShiftSharedResourcesNamespace)
124-
for i := range openshiftRoleBindings {
125-
originObject := &authorizationapi.RoleBinding{}
126-
if err := kapi.Scheme.Convert(&openshiftRoleBindings[i], originObject, nil); err != nil {
127-
return err
142+
openshiftRoleBindings := map[string][]rbac.RoleBinding{}
143+
for namespace, roleBindings := range policy.RoleBindings {
144+
if namespace == bootstrappolicy.DefaultOpenShiftSharedResourcesNamespace {
145+
rb := make([]rbac.RoleBinding, len(roleBindings))
146+
for i := range roleBindings {
147+
rb[i] = roleBindings[i]
148+
rb[i].Namespace = o.OpenShiftSharedResourcesNamespace
149+
}
150+
openshiftRoleBindings[o.OpenShiftSharedResourcesNamespace] = rb
151+
} else {
152+
openshiftRoleBindings[namespace] = roleBindings
128153
}
129-
versionedObject, err := kapi.Scheme.ConvertToVersion(originObject, latest.Version)
130-
if err != nil {
131-
return err
154+
}
155+
156+
// iterate in a defined order
157+
for _, namespace := range sets.StringKeySet(openshiftRoleBindings).List() {
158+
roleBindings := openshiftRoleBindings[namespace]
159+
for i := range roleBindings {
160+
originObject := &authorizationapi.RoleBinding{}
161+
if err := kapi.Scheme.Convert(&roleBindings[i], originObject, nil); err != nil {
162+
return err
163+
}
164+
versionedObject, err := kapi.Scheme.ConvertToVersion(originObject, latest.Version)
165+
if err != nil {
166+
return err
167+
}
168+
policyTemplate.Objects = append(policyTemplate.Objects, versionedObject)
132169
}
133-
policyTemplate.Objects = append(policyTemplate.Objects, versionedObject)
134170
}
135171

136172
versionedPolicyTemplate, err := kapi.Scheme.ConvertToVersion(policyTemplate, latest.Version)

Diff for: pkg/cmd/server/bootstrappolicy/all.go

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
package bootstrappolicy
22

33
import (
4-
"k8s.io/kubernetes/pkg/apis/rbac"
54
rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
65
)
76

87
func Policy() *rbacrest.PolicyData {
98
return &rbacrest.PolicyData{
109
ClusterRoles: GetBootstrapClusterRoles(),
1110
ClusterRoleBindings: GetBootstrapClusterRoleBindings(),
12-
Roles: map[string][]rbac.Role{
13-
DefaultOpenShiftSharedResourcesNamespace: GetBootstrapOpenshiftRoles(DefaultOpenShiftSharedResourcesNamespace),
14-
},
15-
RoleBindings: map[string][]rbac.RoleBinding{
16-
DefaultOpenShiftSharedResourcesNamespace: GetBootstrapOpenshiftRoleBindings(DefaultOpenShiftSharedResourcesNamespace),
17-
},
11+
Roles: GetBootstrapNamespaceRoles(),
12+
RoleBindings: GetBootstrapNamespaceRoleBindings(),
1813
}
1914
}

Diff for: pkg/cmd/server/bootstrappolicy/controller_policy.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,12 @@ func addControllerRoleToSA(saNamespace, saName string, role rbac.ClusterRole) {
7777
}
7878
}
7979

80+
addDefaultMetadata(&role)
8081
controllerRoles = append(controllerRoles, role)
8182

82-
controllerRoleBindings = append(controllerRoleBindings,
83-
rbac.NewClusterBinding(role.Name).SAs(saNamespace, saName).BindingOrDie())
83+
roleBinding := rbac.NewClusterBinding(role.Name).SAs(saNamespace, saName).BindingOrDie()
84+
addDefaultMetadata(&roleBinding)
85+
controllerRoleBindings = append(controllerRoleBindings, roleBinding)
8486
}
8587

8688
func eventsRule() rbac.PolicyRule {
@@ -167,8 +169,9 @@ func init() {
167169
})
168170

169171
// template-instance-controller
170-
controllerRoleBindings = append(controllerRoleBindings,
171-
rbac.NewClusterBinding(AdminRoleName).SAs(DefaultOpenShiftInfraNamespace, InfraTemplateInstanceControllerServiceAccountName).BindingOrDie())
172+
templateInstanceController := rbac.NewClusterBinding(AdminRoleName).SAs(DefaultOpenShiftInfraNamespace, InfraTemplateInstanceControllerServiceAccountName).BindingOrDie()
173+
addDefaultMetadata(&templateInstanceController)
174+
controllerRoleBindings = append(controllerRoleBindings, templateInstanceController)
172175

173176
// origin-namespace-controller
174177
addControllerRole(rbac.ClusterRole{

Diff for: pkg/cmd/server/bootstrappolicy/dead.go

+11-11
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ func addDeadClusterRole(name string) {
2020
}
2121
}
2222

23-
deadClusterRoles = append(deadClusterRoles,
24-
rbac.ClusterRole{
25-
ObjectMeta: metav1.ObjectMeta{Name: name},
26-
},
27-
)
23+
deadClusterRole := rbac.ClusterRole{
24+
ObjectMeta: metav1.ObjectMeta{Name: name},
25+
}
26+
addDefaultMetadata(&deadClusterRole)
27+
deadClusterRoles = append(deadClusterRoles, deadClusterRole)
2828
}
2929

3030
func addDeadClusterRoleBinding(name, roleName string) {
@@ -34,12 +34,12 @@ func addDeadClusterRoleBinding(name, roleName string) {
3434
}
3535
}
3636

37-
deadClusterRoleBindings = append(deadClusterRoleBindings,
38-
rbac.ClusterRoleBinding{
39-
ObjectMeta: metav1.ObjectMeta{Name: name},
40-
RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "ClusterRole", Name: roleName},
41-
},
42-
)
37+
deadClusterRoleBinding := rbac.ClusterRoleBinding{
38+
ObjectMeta: metav1.ObjectMeta{Name: name},
39+
RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "ClusterRole", Name: roleName},
40+
}
41+
addDefaultMetadata(&deadClusterRoleBinding)
42+
deadClusterRoleBindings = append(deadClusterRoleBindings, deadClusterRoleBinding)
4343
}
4444

4545
// GetDeadClusterRoles returns cluster roles which should no longer have any permissions.

Diff for: pkg/cmd/server/bootstrappolicy/namespace_policy.go

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package bootstrappolicy
2+
3+
import (
4+
"strings"
5+
6+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7+
"k8s.io/kubernetes/pkg/apis/rbac"
8+
9+
"github.com/golang/glog"
10+
)
11+
12+
func addNamespaceRole(namespaceRoles map[string][]rbac.Role, namespace string, role rbac.Role) {
13+
if namespace != "openshift" && !strings.HasPrefix(namespace, "openshift-") {
14+
glog.Fatalf(`roles can only be bootstrapped into reserved "openshift" namespace or namespaces starting with "openshift-", not %q`, namespace)
15+
}
16+
17+
existingRoles := namespaceRoles[namespace]
18+
for _, existingRole := range existingRoles {
19+
if role.Name == existingRole.Name {
20+
glog.Fatalf("role %q was already registered in %q", role.Name, namespace)
21+
}
22+
}
23+
24+
role.Namespace = namespace
25+
addDefaultMetadata(&role)
26+
existingRoles = append(existingRoles, role)
27+
namespaceRoles[namespace] = existingRoles
28+
}
29+
30+
func addNamespaceRoleBinding(namespaceRoleBindings map[string][]rbac.RoleBinding, namespace string, roleBinding rbac.RoleBinding) {
31+
if namespace != "openshift" && !strings.HasPrefix(namespace, "openshift-") {
32+
glog.Fatalf(`role bindings can only be bootstrapped into reserved "openshift" namespace or namespaces starting with "openshift-", not %q`, namespace)
33+
}
34+
35+
existingRoleBindings := namespaceRoleBindings[namespace]
36+
for _, existingRoleBinding := range existingRoleBindings {
37+
if roleBinding.Name == existingRoleBinding.Name {
38+
glog.Fatalf("rolebinding %q was already registered in %q", roleBinding.Name, namespace)
39+
}
40+
}
41+
42+
roleBinding.Namespace = namespace
43+
addDefaultMetadata(&roleBinding)
44+
existingRoleBindings = append(existingRoleBindings, roleBinding)
45+
namespaceRoleBindings[namespace] = existingRoleBindings
46+
}
47+
48+
func buildNamespaceRolesAndBindings() (map[string][]rbac.Role, map[string][]rbac.RoleBinding) {
49+
// namespaceRoles is a map of namespace to slice of roles to create
50+
namespaceRoles := map[string][]rbac.Role{}
51+
// namespaceRoleBindings is a map of namespace to slice of roleBindings to create
52+
namespaceRoleBindings := map[string][]rbac.RoleBinding{}
53+
54+
addNamespaceRole(namespaceRoles,
55+
DefaultOpenShiftSharedResourcesNamespace,
56+
rbac.Role{
57+
ObjectMeta: metav1.ObjectMeta{Name: OpenshiftSharedResourceViewRoleName},
58+
Rules: []rbac.PolicyRule{
59+
rbac.NewRule(read...).Groups(templateGroup, legacyTemplateGroup).Resources("templates").RuleOrDie(),
60+
rbac.NewRule(read...).Groups(imageGroup, legacyImageGroup).Resources("imagestreams", "imagestreamtags", "imagestreamimages").RuleOrDie(),
61+
// so anyone can pull from openshift/* image streams
62+
rbac.NewRule("get").Groups(imageGroup, legacyImageGroup).Resources("imagestreams/layers").RuleOrDie(),
63+
},
64+
})
65+
66+
addNamespaceRoleBinding(namespaceRoleBindings,
67+
DefaultOpenShiftSharedResourcesNamespace,
68+
newOriginRoleBinding(OpenshiftSharedResourceViewRoleBindingName, OpenshiftSharedResourceViewRoleName, DefaultOpenShiftSharedResourcesNamespace).Groups(AuthenticatedGroup).BindingOrDie())
69+
70+
return namespaceRoles, namespaceRoleBindings
71+
}
72+
73+
// NamespaceRoles returns a map of namespace to slice of roles to create
74+
func NamespaceRoles() map[string][]rbac.Role {
75+
namespaceRoles, _ := buildNamespaceRolesAndBindings()
76+
return namespaceRoles
77+
}
78+
79+
// NamespaceRoleBindings returns a map of namespace to slice of role bindings to create
80+
func NamespaceRoleBindings() map[string][]rbac.RoleBinding {
81+
_, namespaceRoleBindings := buildNamespaceRolesAndBindings()
82+
return namespaceRoleBindings
83+
}

0 commit comments

Comments
 (0)