Browse code

split cluster policy from local policy

deads2k authored on 2015/05/05 04:43:57
Showing 69 changed files
... ...
@@ -447,8 +447,12 @@ openshift admin policy add-role-to-group cluster-admin system:unauthenticated
447 447
 openshift admin policy remove-role-from-group cluster-admin system:unauthenticated
448 448
 openshift admin policy remove-role-from-group-from-project system:unauthenticated
449 449
 openshift admin policy add-role-to-user cluster-admin system:no-user
450
-openshift admin policy remove-user cluster-admin system:no-user
450
+openshift admin policy remove-role-from-user cluster-admin system:no-user
451 451
 openshift admin policy remove-user-from-project system:no-user
452
+openshift admin policy add-cluster-role-to-group cluster-admin system:unauthenticated
453
+openshift admin policy remove-cluster-role-from-group cluster-admin system:unauthenticated
454
+openshift admin policy add-cluster-role-to-user cluster-admin system:no-user
455
+openshift admin policy remove-cluster-role-from-user cluster-admin system:no-user
452 456
 echo "ex policy: ok"
453 457
 
454 458
 # Test the commands the UI projects page tells users to run
... ...
@@ -458,8 +462,8 @@ osadm policy add-role-to-user admin adduser -n ui-test-project
458 458
 # Make sure project can be listed by osc (after auth cache syncs)
459 459
 sleep 2 && [ "$(osc get projects | grep 'ui-test-project')" ]
460 460
 # Make sure users got added
461
-[ "$(osc describe policybinding master:default -n ui-test-project | grep createuser)" ]
462
-[ "$(osc describe policybinding master:default -n ui-test-project | grep adduser)" ]
461
+[ "$(osc describe policybinding ':default' -n ui-test-project | grep createuser)" ]
462
+[ "$(osc describe policybinding ':default' -n ui-test-project | grep adduser)" ]
463 463
 echo "ui-project-commands: ok"
464 464
 
465 465
 # Test deleting and recreating a project
... ...
@@ -467,7 +471,7 @@ osadm new-project recreated-project --admin="createuser1"
467 467
 osc delete project recreated-project
468 468
 wait_for_command '! osc get project recreated-project' "${TIME_MIN}"
469 469
 osadm new-project recreated-project --admin="createuser2"
470
-osc describe policybinding master:default -n recreated-project | grep createuser2
470
+osc describe policybinding ':default' -n recreated-project | grep createuser2
471 471
 echo "ex new-project: ok"
472 472
 
473 473
 # Test running a router
... ...
@@ -4,76 +4,72 @@ import (
4 4
 	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
5 5
 )
6 6
 
7
-type TypeConverter struct {
8
-	MasterNamespace string
9
-}
10
-
11 7
 // policies
12 8
 
13
-func (t TypeConverter) ToPolicyList(in *ClusterPolicyList) *PolicyList {
9
+func ToPolicyList(in *ClusterPolicyList) *PolicyList {
14 10
 	ret := &PolicyList{}
15 11
 	for _, curr := range in.Items {
16
-		ret.Items = append(ret.Items, *t.ToPolicy(&curr))
12
+		ret.Items = append(ret.Items, *ToPolicy(&curr))
17 13
 	}
18 14
 
19 15
 	return ret
20 16
 }
21 17
 
22
-func (t TypeConverter) ToPolicy(in *ClusterPolicy) *Policy {
18
+func ToPolicy(in *ClusterPolicy) *Policy {
23 19
 	if in == nil {
24 20
 		return nil
25 21
 	}
26 22
 
27 23
 	ret := &Policy{}
28 24
 	ret.ObjectMeta = in.ObjectMeta
29
-	ret.Namespace = t.MasterNamespace
25
+	ret.Namespace = ""
30 26
 	ret.LastModified = in.LastModified
31
-	ret.Roles = t.ToRoleMap(in.Roles)
27
+	ret.Roles = ToRoleMap(in.Roles)
32 28
 
33 29
 	return ret
34 30
 }
35 31
 
36
-func (t TypeConverter) ToRoleMap(in map[string]ClusterRole) map[string]Role {
32
+func ToRoleMap(in map[string]ClusterRole) map[string]Role {
37 33
 	ret := map[string]Role{}
38 34
 	for key, role := range in {
39
-		ret[key] = *t.ToRole(&role)
35
+		ret[key] = *ToRole(&role)
40 36
 	}
41 37
 
42 38
 	return ret
43 39
 }
44 40
 
45
-func (t TypeConverter) ToRoleList(in *ClusterRoleList) *RoleList {
41
+func ToRoleList(in *ClusterRoleList) *RoleList {
46 42
 	ret := &RoleList{}
47 43
 	for _, curr := range in.Items {
48
-		ret.Items = append(ret.Items, *t.ToRole(&curr))
44
+		ret.Items = append(ret.Items, *ToRole(&curr))
49 45
 	}
50 46
 
51 47
 	return ret
52 48
 }
53 49
 
54
-func (t TypeConverter) ToRole(in *ClusterRole) *Role {
50
+func ToRole(in *ClusterRole) *Role {
55 51
 	if in == nil {
56 52
 		return nil
57 53
 	}
58 54
 
59 55
 	ret := &Role{}
60 56
 	ret.ObjectMeta = in.ObjectMeta
61
-	ret.Namespace = t.MasterNamespace
57
+	ret.Namespace = ""
62 58
 	ret.Rules = in.Rules
63 59
 
64 60
 	return ret
65 61
 }
66 62
 
67
-func (t TypeConverter) ToClusterPolicyList(in *PolicyList) *ClusterPolicyList {
63
+func ToClusterPolicyList(in *PolicyList) *ClusterPolicyList {
68 64
 	ret := &ClusterPolicyList{}
69 65
 	for _, curr := range in.Items {
70
-		ret.Items = append(ret.Items, *t.ToClusterPolicy(&curr))
66
+		ret.Items = append(ret.Items, *ToClusterPolicy(&curr))
71 67
 	}
72 68
 
73 69
 	return ret
74 70
 }
75 71
 
76
-func (t TypeConverter) ToClusterPolicy(in *Policy) *ClusterPolicy {
72
+func ToClusterPolicy(in *Policy) *ClusterPolicy {
77 73
 	if in == nil {
78 74
 		return nil
79 75
 	}
... ...
@@ -82,30 +78,30 @@ func (t TypeConverter) ToClusterPolicy(in *Policy) *ClusterPolicy {
82 82
 	ret.ObjectMeta = in.ObjectMeta
83 83
 	ret.Namespace = ""
84 84
 	ret.LastModified = in.LastModified
85
-	ret.Roles = t.ToClusterRoleMap(in.Roles)
85
+	ret.Roles = ToClusterRoleMap(in.Roles)
86 86
 
87 87
 	return ret
88 88
 }
89 89
 
90
-func (t TypeConverter) ToClusterRoleMap(in map[string]Role) map[string]ClusterRole {
90
+func ToClusterRoleMap(in map[string]Role) map[string]ClusterRole {
91 91
 	ret := map[string]ClusterRole{}
92 92
 	for key, role := range in {
93
-		ret[key] = *t.ToClusterRole(&role)
93
+		ret[key] = *ToClusterRole(&role)
94 94
 	}
95 95
 
96 96
 	return ret
97 97
 }
98 98
 
99
-func (t TypeConverter) ToClusterRoleList(in *RoleList) *ClusterRoleList {
99
+func ToClusterRoleList(in *RoleList) *ClusterRoleList {
100 100
 	ret := &ClusterRoleList{}
101 101
 	for _, curr := range in.Items {
102
-		ret.Items = append(ret.Items, *t.ToClusterRole(&curr))
102
+		ret.Items = append(ret.Items, *ToClusterRole(&curr))
103 103
 	}
104 104
 
105 105
 	return ret
106 106
 }
107 107
 
108
-func (t TypeConverter) ToClusterRole(in *Role) *ClusterRole {
108
+func ToClusterRole(in *Role) *ClusterRole {
109 109
 	if in == nil {
110 110
 		return nil
111 111
 	}
... ...
@@ -120,86 +116,86 @@ func (t TypeConverter) ToClusterRole(in *Role) *ClusterRole {
120 120
 
121 121
 // policy bindings
122 122
 
123
-func (t TypeConverter) ToPolicyBindingList(in *ClusterPolicyBindingList) *PolicyBindingList {
123
+func ToPolicyBindingList(in *ClusterPolicyBindingList) *PolicyBindingList {
124 124
 	ret := &PolicyBindingList{}
125 125
 	for _, curr := range in.Items {
126
-		ret.Items = append(ret.Items, *t.ToPolicyBinding(&curr))
126
+		ret.Items = append(ret.Items, *ToPolicyBinding(&curr))
127 127
 	}
128 128
 
129 129
 	return ret
130 130
 }
131 131
 
132
-func (t TypeConverter) ToPolicyBinding(in *ClusterPolicyBinding) *PolicyBinding {
132
+func ToPolicyBinding(in *ClusterPolicyBinding) *PolicyBinding {
133 133
 	if in == nil {
134 134
 		return nil
135 135
 	}
136 136
 
137 137
 	ret := &PolicyBinding{}
138 138
 	ret.ObjectMeta = in.ObjectMeta
139
-	ret.Namespace = t.MasterNamespace
139
+	ret.Namespace = ""
140 140
 	ret.LastModified = in.LastModified
141
-	ret.PolicyRef = t.ToPolicyRef(in.PolicyRef)
142
-	ret.RoleBindings = t.ToRoleBindingMap(in.RoleBindings)
141
+	ret.PolicyRef = ToPolicyRef(in.PolicyRef)
142
+	ret.RoleBindings = ToRoleBindingMap(in.RoleBindings)
143 143
 
144 144
 	return ret
145 145
 }
146 146
 
147
-func (t TypeConverter) ToPolicyRef(in kapi.ObjectReference) kapi.ObjectReference {
147
+func ToPolicyRef(in kapi.ObjectReference) kapi.ObjectReference {
148 148
 	ret := kapi.ObjectReference{}
149
-	ret.Namespace = t.MasterNamespace
149
+	ret.Namespace = ""
150 150
 	ret.Name = in.Name
151 151
 	return ret
152 152
 }
153 153
 
154
-func (t TypeConverter) ToRoleBindingMap(in map[string]ClusterRoleBinding) map[string]RoleBinding {
154
+func ToRoleBindingMap(in map[string]ClusterRoleBinding) map[string]RoleBinding {
155 155
 	ret := map[string]RoleBinding{}
156 156
 	for key, RoleBinding := range in {
157
-		ret[key] = *t.ToRoleBinding(&RoleBinding)
157
+		ret[key] = *ToRoleBinding(&RoleBinding)
158 158
 	}
159 159
 
160 160
 	return ret
161 161
 }
162 162
 
163
-func (t TypeConverter) ToRoleBindingList(in *ClusterRoleBindingList) *RoleBindingList {
163
+func ToRoleBindingList(in *ClusterRoleBindingList) *RoleBindingList {
164 164
 	ret := &RoleBindingList{}
165 165
 	for _, curr := range in.Items {
166
-		ret.Items = append(ret.Items, *t.ToRoleBinding(&curr))
166
+		ret.Items = append(ret.Items, *ToRoleBinding(&curr))
167 167
 	}
168 168
 
169 169
 	return ret
170 170
 }
171 171
 
172
-func (t TypeConverter) ToRoleBinding(in *ClusterRoleBinding) *RoleBinding {
172
+func ToRoleBinding(in *ClusterRoleBinding) *RoleBinding {
173 173
 	if in == nil {
174 174
 		return nil
175 175
 	}
176 176
 
177 177
 	ret := &RoleBinding{}
178 178
 	ret.ObjectMeta = in.ObjectMeta
179
-	ret.Namespace = t.MasterNamespace
179
+	ret.Namespace = ""
180 180
 	ret.Users = in.Users
181 181
 	ret.Groups = in.Groups
182
-	ret.RoleRef = t.ToRoleRef(in.RoleRef)
182
+	ret.RoleRef = ToRoleRef(in.RoleRef)
183 183
 	return ret
184 184
 }
185 185
 
186
-func (t TypeConverter) ToRoleRef(in kapi.ObjectReference) kapi.ObjectReference {
186
+func ToRoleRef(in kapi.ObjectReference) kapi.ObjectReference {
187 187
 	ret := kapi.ObjectReference{}
188
-	ret.Namespace = t.MasterNamespace
188
+	ret.Namespace = ""
189 189
 	ret.Name = in.Name
190 190
 	return ret
191 191
 }
192 192
 
193
-func (t TypeConverter) ToClusterPolicyBindingList(in *PolicyBindingList) *ClusterPolicyBindingList {
193
+func ToClusterPolicyBindingList(in *PolicyBindingList) *ClusterPolicyBindingList {
194 194
 	ret := &ClusterPolicyBindingList{}
195 195
 	for _, curr := range in.Items {
196
-		ret.Items = append(ret.Items, *t.ToClusterPolicyBinding(&curr))
196
+		ret.Items = append(ret.Items, *ToClusterPolicyBinding(&curr))
197 197
 	}
198 198
 
199 199
 	return ret
200 200
 }
201 201
 
202
-func (t TypeConverter) ToClusterPolicyBinding(in *PolicyBinding) *ClusterPolicyBinding {
202
+func ToClusterPolicyBinding(in *PolicyBinding) *ClusterPolicyBinding {
203 203
 	if in == nil {
204 204
 		return nil
205 205
 	}
... ...
@@ -208,38 +204,38 @@ func (t TypeConverter) ToClusterPolicyBinding(in *PolicyBinding) *ClusterPolicyB
208 208
 	ret.ObjectMeta = in.ObjectMeta
209 209
 	ret.Namespace = ""
210 210
 	ret.LastModified = in.LastModified
211
-	ret.PolicyRef = t.ToClusterPolicyRef(in.PolicyRef)
212
-	ret.RoleBindings = t.ToClusterRoleBindingMap(in.RoleBindings)
211
+	ret.PolicyRef = ToClusterPolicyRef(in.PolicyRef)
212
+	ret.RoleBindings = ToClusterRoleBindingMap(in.RoleBindings)
213 213
 
214 214
 	return ret
215 215
 }
216 216
 
217
-func (t TypeConverter) ToClusterPolicyRef(in kapi.ObjectReference) kapi.ObjectReference {
217
+func ToClusterPolicyRef(in kapi.ObjectReference) kapi.ObjectReference {
218 218
 	ret := kapi.ObjectReference{}
219 219
 	ret.Namespace = ""
220 220
 	ret.Name = in.Name
221 221
 	return ret
222 222
 }
223 223
 
224
-func (t TypeConverter) ToClusterRoleBindingMap(in map[string]RoleBinding) map[string]ClusterRoleBinding {
224
+func ToClusterRoleBindingMap(in map[string]RoleBinding) map[string]ClusterRoleBinding {
225 225
 	ret := map[string]ClusterRoleBinding{}
226 226
 	for key, RoleBinding := range in {
227
-		ret[key] = *t.ToClusterRoleBinding(&RoleBinding)
227
+		ret[key] = *ToClusterRoleBinding(&RoleBinding)
228 228
 	}
229 229
 
230 230
 	return ret
231 231
 }
232 232
 
233
-func (t TypeConverter) ToClusterRoleBindingList(in *RoleBindingList) *ClusterRoleBindingList {
233
+func ToClusterRoleBindingList(in *RoleBindingList) *ClusterRoleBindingList {
234 234
 	ret := &ClusterRoleBindingList{}
235 235
 	for _, curr := range in.Items {
236
-		ret.Items = append(ret.Items, *t.ToClusterRoleBinding(&curr))
236
+		ret.Items = append(ret.Items, *ToClusterRoleBinding(&curr))
237 237
 	}
238 238
 
239 239
 	return ret
240 240
 }
241 241
 
242
-func (t TypeConverter) ToClusterRoleBinding(in *RoleBinding) *ClusterRoleBinding {
242
+func ToClusterRoleBinding(in *RoleBinding) *ClusterRoleBinding {
243 243
 	if in == nil {
244 244
 		return nil
245 245
 	}
... ...
@@ -249,12 +245,12 @@ func (t TypeConverter) ToClusterRoleBinding(in *RoleBinding) *ClusterRoleBinding
249 249
 	ret.Namespace = ""
250 250
 	ret.Users = in.Users
251 251
 	ret.Groups = in.Groups
252
-	ret.RoleRef = t.ToClusterRoleRef(in.RoleRef)
252
+	ret.RoleRef = ToClusterRoleRef(in.RoleRef)
253 253
 
254 254
 	return ret
255 255
 }
256 256
 
257
-func (t TypeConverter) ToClusterRoleRef(in kapi.ObjectReference) kapi.ObjectReference {
257
+func ToClusterRoleRef(in kapi.ObjectReference) kapi.ObjectReference {
258 258
 	ret := kapi.ObjectReference{}
259 259
 	ret.Namespace = ""
260 260
 	ret.Name = in.Name
... ...
@@ -83,3 +83,5 @@ func (s RoleBindingSorter) Swap(i, j int) {
83 83
 func GetPolicyBindingName(policyRefNamespace string) string {
84 84
 	return fmt.Sprintf("%s:%s", policyRefNamespace, PolicyName)
85 85
 }
86
+
87
+var ClusterPolicyBindingName = GetPolicyBindingName("")
... ...
@@ -18,23 +18,39 @@ func ValidatePolicyName(name string, prefix bool) (bool, string) {
18 18
 	return true, ""
19 19
 }
20 20
 
21
-func ValidatePolicy(policy *authorizationapi.Policy) fielderrors.ValidationErrorList {
21
+func ValidateLocalPolicy(policy *authorizationapi.Policy) fielderrors.ValidationErrorList {
22
+	return ValidatePolicy(policy, true)
23
+}
24
+
25
+func ValidateLocalPolicyUpdate(policy *authorizationapi.Policy, oldPolicy *authorizationapi.Policy) fielderrors.ValidationErrorList {
26
+	return ValidatePolicyUpdate(policy, oldPolicy, true)
27
+}
28
+
29
+func ValidateClusterPolicy(policy *authorizationapi.ClusterPolicy) fielderrors.ValidationErrorList {
30
+	return ValidatePolicy(authorizationapi.ToPolicy(policy), false)
31
+}
32
+
33
+func ValidateClusterPolicyUpdate(policy *authorizationapi.ClusterPolicy, oldPolicy *authorizationapi.ClusterPolicy) fielderrors.ValidationErrorList {
34
+	return ValidatePolicyUpdate(authorizationapi.ToPolicy(policy), authorizationapi.ToPolicy(oldPolicy), false)
35
+}
36
+
37
+func ValidatePolicy(policy *authorizationapi.Policy, isNamespaced bool) fielderrors.ValidationErrorList {
22 38
 	allErrs := fielderrors.ValidationErrorList{}
23
-	allErrs = append(allErrs, validation.ValidateObjectMeta(&policy.ObjectMeta, true, ValidatePolicyName).Prefix("metadata")...)
39
+	allErrs = append(allErrs, validation.ValidateObjectMeta(&policy.ObjectMeta, isNamespaced, ValidatePolicyName).Prefix("metadata")...)
24 40
 
25 41
 	for roleKey, role := range policy.Roles {
26 42
 		if roleKey != role.Name {
27 43
 			allErrs = append(allErrs, fielderrors.NewFieldInvalid("roles."+roleKey+".metadata.name", role.Name, "must be "+roleKey))
28 44
 		}
29 45
 
30
-		allErrs = append(allErrs, ValidateRole(&role).Prefix("roles."+roleKey)...)
46
+		allErrs = append(allErrs, ValidateRole(&role, isNamespaced).Prefix("roles."+roleKey)...)
31 47
 	}
32 48
 
33 49
 	return allErrs
34 50
 }
35 51
 
36
-func ValidatePolicyUpdate(policy *authorizationapi.Policy, oldPolicy *authorizationapi.Policy) fielderrors.ValidationErrorList {
37
-	allErrs := ValidatePolicy(policy)
52
+func ValidatePolicyUpdate(policy *authorizationapi.Policy, oldPolicy *authorizationapi.Policy, isNamespaced bool) fielderrors.ValidationErrorList {
53
+	allErrs := ValidatePolicy(policy, isNamespaced)
38 54
 	allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(&oldPolicy.ObjectMeta, &policy.ObjectMeta).Prefix("metadata")...)
39 55
 
40 56
 	return allErrs
... ...
@@ -50,13 +66,30 @@ func PolicyBindingNameValidator(policyRefNamespace string) validation.ValidateNa
50 50
 	}
51 51
 }
52 52
 
53
-// ValidatePolicyBinding tests required fields for a PolicyBinding.
54
-func ValidatePolicyBinding(policyBinding *authorizationapi.PolicyBinding) fielderrors.ValidationErrorList {
53
+func ValidateLocalPolicyBinding(policy *authorizationapi.PolicyBinding) fielderrors.ValidationErrorList {
54
+	return ValidatePolicyBinding(policy, true)
55
+}
56
+
57
+func ValidateLocalPolicyBindingUpdate(policy *authorizationapi.PolicyBinding, oldPolicyBinding *authorizationapi.PolicyBinding) fielderrors.ValidationErrorList {
58
+	return ValidatePolicyBindingUpdate(policy, oldPolicyBinding, true)
59
+}
60
+
61
+func ValidateClusterPolicyBinding(policy *authorizationapi.ClusterPolicyBinding) fielderrors.ValidationErrorList {
62
+	return ValidatePolicyBinding(authorizationapi.ToPolicyBinding(policy), false)
63
+}
64
+
65
+func ValidateClusterPolicyBindingUpdate(policy *authorizationapi.ClusterPolicyBinding, oldPolicyBinding *authorizationapi.ClusterPolicyBinding) fielderrors.ValidationErrorList {
66
+	return ValidatePolicyBindingUpdate(authorizationapi.ToPolicyBinding(policy), authorizationapi.ToPolicyBinding(oldPolicyBinding), false)
67
+}
68
+
69
+func ValidatePolicyBinding(policyBinding *authorizationapi.PolicyBinding, isNamespaced bool) fielderrors.ValidationErrorList {
55 70
 	allErrs := fielderrors.ValidationErrorList{}
56
-	allErrs = append(allErrs, validation.ValidateObjectMeta(&policyBinding.ObjectMeta, true, PolicyBindingNameValidator(policyBinding.PolicyRef.Namespace)).Prefix("metadata")...)
71
+	allErrs = append(allErrs, validation.ValidateObjectMeta(&policyBinding.ObjectMeta, isNamespaced, PolicyBindingNameValidator(policyBinding.PolicyRef.Namespace)).Prefix("metadata")...)
57 72
 
58
-	if len(policyBinding.PolicyRef.Namespace) == 0 {
59
-		allErrs = append(allErrs, fielderrors.NewFieldRequired("policyRef.namespace"))
73
+	if !isNamespaced {
74
+		if len(policyBinding.PolicyRef.Namespace) > 0 {
75
+			allErrs = append(allErrs, fielderrors.NewFieldInvalid("policyRef.namespace", policyBinding.PolicyRef.Namespace, "may not reference another namespace"))
76
+		}
60 77
 	}
61 78
 
62 79
 	for roleBindingKey, roleBinding := range policyBinding.RoleBindings {
... ...
@@ -68,14 +101,14 @@ func ValidatePolicyBinding(policyBinding *authorizationapi.PolicyBinding) fielde
68 68
 			allErrs = append(allErrs, fielderrors.NewFieldInvalid("roleBindings."+roleBindingKey+".metadata.name", roleBinding.Name, "must be "+roleBindingKey))
69 69
 		}
70 70
 
71
-		allErrs = append(allErrs, ValidateRoleBinding(&roleBinding).Prefix("roleBindings."+roleBindingKey)...)
71
+		allErrs = append(allErrs, ValidateRoleBinding(&roleBinding, isNamespaced).Prefix("roleBindings."+roleBindingKey)...)
72 72
 	}
73 73
 
74 74
 	return allErrs
75 75
 }
76 76
 
77
-func ValidatePolicyBindingUpdate(policyBinding *authorizationapi.PolicyBinding, oldPolicyBinding *authorizationapi.PolicyBinding) fielderrors.ValidationErrorList {
78
-	allErrs := ValidatePolicyBinding(policyBinding)
77
+func ValidatePolicyBindingUpdate(policyBinding *authorizationapi.PolicyBinding, oldPolicyBinding *authorizationapi.PolicyBinding, isNamespaced bool) fielderrors.ValidationErrorList {
78
+	allErrs := ValidatePolicyBinding(policyBinding, isNamespaced)
79 79
 	allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(&oldPolicyBinding.ObjectMeta, &policyBinding.ObjectMeta).Prefix("metadata")...)
80 80
 
81 81
 	if oldPolicyBinding.PolicyRef.Namespace != policyBinding.PolicyRef.Namespace {
... ...
@@ -95,16 +128,31 @@ func ValidateRoleName(name string, prefix bool) (bool, string) {
95 95
 	return true, ""
96 96
 }
97 97
 
98
-// ValidateRole tests required fields for a Role.
99
-func ValidateRole(role *authorizationapi.Role) fielderrors.ValidationErrorList {
98
+func ValidateLocalRole(policy *authorizationapi.Role) fielderrors.ValidationErrorList {
99
+	return ValidateRole(policy, true)
100
+}
101
+
102
+func ValidateLocalRoleUpdate(policy *authorizationapi.Role, oldRole *authorizationapi.Role) fielderrors.ValidationErrorList {
103
+	return ValidateRoleUpdate(policy, oldRole, true)
104
+}
105
+
106
+func ValidateClusterRole(policy *authorizationapi.ClusterRole) fielderrors.ValidationErrorList {
107
+	return ValidateRole(authorizationapi.ToRole(policy), false)
108
+}
109
+
110
+func ValidateClusterRoleUpdate(policy *authorizationapi.ClusterRole, oldRole *authorizationapi.ClusterRole) fielderrors.ValidationErrorList {
111
+	return ValidateRoleUpdate(authorizationapi.ToRole(policy), authorizationapi.ToRole(oldRole), false)
112
+}
113
+
114
+func ValidateRole(role *authorizationapi.Role, isNamespaced bool) fielderrors.ValidationErrorList {
100 115
 	allErrs := fielderrors.ValidationErrorList{}
101
-	allErrs = append(allErrs, validation.ValidateObjectMeta(&role.ObjectMeta, true, ValidateRoleName).Prefix("metadata")...)
116
+	allErrs = append(allErrs, validation.ValidateObjectMeta(&role.ObjectMeta, isNamespaced, ValidateRoleName).Prefix("metadata")...)
102 117
 
103 118
 	return allErrs
104 119
 }
105 120
 
106
-func ValidateRoleUpdate(role *authorizationapi.Role, oldRole *authorizationapi.Role) fielderrors.ValidationErrorList {
107
-	allErrs := ValidateRole(role)
121
+func ValidateRoleUpdate(role *authorizationapi.Role, oldRole *authorizationapi.Role, isNamespaced bool) fielderrors.ValidationErrorList {
122
+	allErrs := ValidateRole(role, isNamespaced)
108 123
 	allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(&oldRole.ObjectMeta, &role.ObjectMeta).Prefix("metadata")...)
109 124
 
110 125
 	return allErrs
... ...
@@ -120,14 +168,28 @@ func ValidateRoleBindingName(name string, prefix bool) (bool, string) {
120 120
 	return true, ""
121 121
 }
122 122
 
123
-// ValidateRoleBinding tests required fields for a RoleBinding.
124
-func ValidateRoleBinding(roleBinding *authorizationapi.RoleBinding) fielderrors.ValidationErrorList {
123
+func ValidateLocalRoleBinding(policy *authorizationapi.RoleBinding) fielderrors.ValidationErrorList {
124
+	return ValidateRoleBinding(policy, true)
125
+}
126
+
127
+func ValidateLocalRoleBindingUpdate(policy *authorizationapi.RoleBinding, oldRoleBinding *authorizationapi.RoleBinding) fielderrors.ValidationErrorList {
128
+	return ValidateRoleBindingUpdate(policy, oldRoleBinding, true)
129
+}
130
+
131
+func ValidateClusterRoleBinding(policy *authorizationapi.ClusterRoleBinding) fielderrors.ValidationErrorList {
132
+	return ValidateRoleBinding(authorizationapi.ToRoleBinding(policy), false)
133
+}
134
+
135
+func ValidateClusterRoleBindingUpdate(policy *authorizationapi.ClusterRoleBinding, oldRoleBinding *authorizationapi.ClusterRoleBinding) fielderrors.ValidationErrorList {
136
+	return ValidateRoleBindingUpdate(authorizationapi.ToRoleBinding(policy), authorizationapi.ToRoleBinding(oldRoleBinding), false)
137
+}
138
+
139
+func ValidateRoleBinding(roleBinding *authorizationapi.RoleBinding, isNamespaced bool) fielderrors.ValidationErrorList {
125 140
 	allErrs := fielderrors.ValidationErrorList{}
126
-	allErrs = append(allErrs, validation.ValidateObjectMeta(&roleBinding.ObjectMeta, true, ValidateRoleBindingName).Prefix("metadata")...)
141
+	allErrs = append(allErrs, validation.ValidateObjectMeta(&roleBinding.ObjectMeta, isNamespaced, ValidateRoleBindingName).Prefix("metadata")...)
127 142
 
128
-	if len(roleBinding.RoleRef.Namespace) == 0 {
129
-		allErrs = append(allErrs, fielderrors.NewFieldRequired("roleRef.namespace"))
130
-	} else if !util.IsDNS1123Subdomain(roleBinding.RoleRef.Namespace) {
143
+	// roleRef namespace is empty when referring to global policy.
144
+	if (len(roleBinding.RoleRef.Namespace) > 0) && !util.IsDNS1123Subdomain(roleBinding.RoleRef.Namespace) {
131 145
 		allErrs = append(allErrs, fielderrors.NewFieldInvalid("roleRef.namespace", roleBinding.RoleRef.Namespace, "roleRef.namespace must be a valid subdomain"))
132 146
 	}
133 147
 
... ...
@@ -142,8 +204,8 @@ func ValidateRoleBinding(roleBinding *authorizationapi.RoleBinding) fielderrors.
142 142
 	return allErrs
143 143
 }
144 144
 
145
-func ValidateRoleBindingUpdate(roleBinding *authorizationapi.RoleBinding, oldRoleBinding *authorizationapi.RoleBinding) fielderrors.ValidationErrorList {
146
-	allErrs := ValidateRoleBinding(roleBinding)
145
+func ValidateRoleBindingUpdate(roleBinding *authorizationapi.RoleBinding, oldRoleBinding *authorizationapi.RoleBinding, isNamespaced bool) fielderrors.ValidationErrorList {
146
+	allErrs := ValidateRoleBinding(roleBinding, isNamespaced)
147 147
 	allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(&oldRoleBinding.ObjectMeta, &roleBinding.ObjectMeta).Prefix("metadata")...)
148 148
 
149 149
 	if oldRoleBinding.RoleRef != roleBinding.RoleRef {
... ...
@@ -10,9 +10,12 @@ import (
10 10
 )
11 11
 
12 12
 func TestValidatePolicy(t *testing.T) {
13
-	errs := ValidatePolicy(&authorizationapi.Policy{
14
-		ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.PolicyName},
15
-	})
13
+	errs := ValidatePolicy(
14
+		&authorizationapi.Policy{
15
+			ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.PolicyName},
16
+		},
17
+		true,
18
+	)
16 19
 	if len(errs) != 0 {
17 20
 		t.Errorf("expected success: %v", errs)
18 21
 	}
... ...
@@ -57,7 +60,7 @@ func TestValidatePolicy(t *testing.T) {
57 57
 		},
58 58
 	}
59 59
 	for k, v := range errorCases {
60
-		errs := ValidatePolicy(&v.A)
60
+		errs := ValidatePolicy(&v.A, true)
61 61
 		if len(errs) == 0 {
62 62
 			t.Errorf("expected failure %s for %v", k, v.A)
63 63
 			continue
... ...
@@ -74,10 +77,13 @@ func TestValidatePolicy(t *testing.T) {
74 74
 }
75 75
 
76 76
 func TestValidatePolicyBinding(t *testing.T) {
77
-	errs := ValidatePolicyBinding(&authorizationapi.PolicyBinding{
78
-		ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.GetPolicyBindingName("master")},
79
-		PolicyRef:  kapi.ObjectReference{Namespace: "master"},
80
-	})
77
+	errs := ValidatePolicyBinding(
78
+		&authorizationapi.PolicyBinding{
79
+			ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: authorizationapi.GetPolicyBindingName("master")},
80
+			PolicyRef:  kapi.ObjectReference{Namespace: "master"},
81
+		},
82
+		true,
83
+	)
81 84
 	if len(errs) != 0 {
82 85
 		t.Errorf("expected success: %v", errs)
83 86
 	}
... ...
@@ -141,7 +147,7 @@ func TestValidatePolicyBinding(t *testing.T) {
141 141
 		},
142 142
 	}
143 143
 	for k, v := range errorCases {
144
-		errs := ValidatePolicyBinding(&v.A)
144
+		errs := ValidatePolicyBinding(&v.A, true)
145 145
 		if len(errs) == 0 {
146 146
 			t.Errorf("expected failure %s for %v", k, v.A)
147 147
 			continue
... ...
@@ -158,10 +164,13 @@ func TestValidatePolicyBinding(t *testing.T) {
158 158
 }
159 159
 
160 160
 func TestValidateRoleBinding(t *testing.T) {
161
-	errs := ValidateRoleBinding(&authorizationapi.RoleBinding{
162
-		ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"},
163
-		RoleRef:    kapi.ObjectReference{Namespace: "master", Name: "valid"},
164
-	})
161
+	errs := ValidateRoleBinding(
162
+		&authorizationapi.RoleBinding{
163
+			ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"},
164
+			RoleRef:    kapi.ObjectReference{Namespace: "master", Name: "valid"},
165
+		},
166
+		true,
167
+	)
165 168
 	if len(errs) != 0 {
166 169
 		t.Errorf("expected success: %v", errs)
167 170
 	}
... ...
@@ -190,9 +199,9 @@ func TestValidateRoleBinding(t *testing.T) {
190 190
 		"invalid ref": {
191 191
 			A: authorizationapi.RoleBinding{
192 192
 				ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "name"},
193
-				RoleRef:    kapi.ObjectReference{Name: "valid"},
193
+				RoleRef:    kapi.ObjectReference{Namespace: "-192083", Name: "valid"},
194 194
 			},
195
-			T: fielderrors.ValidationErrorTypeRequired,
195
+			T: fielderrors.ValidationErrorTypeInvalid,
196 196
 			F: "roleRef.namespace",
197 197
 		},
198 198
 		"bad role": {
... ...
@@ -205,7 +214,7 @@ func TestValidateRoleBinding(t *testing.T) {
205 205
 		},
206 206
 	}
207 207
 	for k, v := range errorCases {
208
-		errs := ValidateRoleBinding(&v.A)
208
+		errs := ValidateRoleBinding(&v.A, true)
209 209
 		if len(errs) == 0 {
210 210
 			t.Errorf("expected failure %s for %v", k, v.A)
211 211
 			continue
... ...
@@ -227,10 +236,14 @@ func TestValidateRoleBindingUpdate(t *testing.T) {
227 227
 		RoleRef:    kapi.ObjectReference{Namespace: "master", Name: "valid"},
228 228
 	}
229 229
 
230
-	errs := ValidateRoleBindingUpdate(&authorizationapi.RoleBinding{
231
-		ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master", ResourceVersion: "1"},
232
-		RoleRef:    kapi.ObjectReference{Namespace: "master", Name: "valid"},
233
-	}, old)
230
+	errs := ValidateRoleBindingUpdate(
231
+		&authorizationapi.RoleBinding{
232
+			ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master", ResourceVersion: "1"},
233
+			RoleRef:    kapi.ObjectReference{Namespace: "master", Name: "valid"},
234
+		},
235
+		old,
236
+		true,
237
+	)
234 238
 	if len(errs) != 0 {
235 239
 		t.Errorf("expected success: %v", errs)
236 240
 	}
... ...
@@ -250,7 +263,7 @@ func TestValidateRoleBindingUpdate(t *testing.T) {
250 250
 		},
251 251
 	}
252 252
 	for k, v := range errorCases {
253
-		errs := ValidateRoleBindingUpdate(&v.A, old)
253
+		errs := ValidateRoleBindingUpdate(&v.A, old, true)
254 254
 		if len(errs) == 0 {
255 255
 			t.Errorf("expected failure %s for %v", k, v.A)
256 256
 			continue
... ...
@@ -267,9 +280,12 @@ func TestValidateRoleBindingUpdate(t *testing.T) {
267 267
 }
268 268
 
269 269
 func TestValidateRole(t *testing.T) {
270
-	errs := ValidateRole(&authorizationapi.Role{
271
-		ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"},
272
-	})
270
+	errs := ValidateRole(
271
+		&authorizationapi.Role{
272
+			ObjectMeta: kapi.ObjectMeta{Namespace: kapi.NamespaceDefault, Name: "master"},
273
+		},
274
+		true,
275
+	)
273 276
 	if len(errs) != 0 {
274 277
 		t.Errorf("expected success: %v", errs)
275 278
 	}
... ...
@@ -295,7 +311,39 @@ func TestValidateRole(t *testing.T) {
295 295
 		},
296 296
 	}
297 297
 	for k, v := range errorCases {
298
-		errs := ValidateRole(&v.A)
298
+		errs := ValidateRole(&v.A, true)
299
+		if len(errs) == 0 {
300
+			t.Errorf("expected failure %s for %v", k, v.A)
301
+			continue
302
+		}
303
+		for i := range errs {
304
+			if errs[i].(*fielderrors.ValidationError).Type != v.T {
305
+				t.Errorf("%s: expected errors to have type %s: %v", k, v.T, errs[i])
306
+			}
307
+			if errs[i].(*fielderrors.ValidationError).Field != v.F {
308
+				t.Errorf("%s: expected errors to have field %s: %v", k, v.F, errs[i])
309
+			}
310
+		}
311
+	}
312
+}
313
+
314
+func TestValidateClusterPolicyBinding(t *testing.T) {
315
+	errorCases := map[string]struct {
316
+		A authorizationapi.PolicyBinding
317
+		T fielderrors.ValidationErrorType
318
+		F string
319
+	}{
320
+		"external namespace ref": {
321
+			A: authorizationapi.PolicyBinding{
322
+				ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.GetPolicyBindingName("master")},
323
+				PolicyRef:  kapi.ObjectReference{Namespace: "master"},
324
+			},
325
+			T: fielderrors.ValidationErrorTypeInvalid,
326
+			F: "policyRef.namespace",
327
+		},
328
+	}
329
+	for k, v := range errorCases {
330
+		errs := ValidatePolicyBinding(&v.A, false)
299 331
 		if len(errs) == 0 {
300 332
 			t.Errorf("expected failure %s for %v", k, v.A)
301 333
 			continue
... ...
@@ -12,12 +12,11 @@ import (
12 12
 )
13 13
 
14 14
 type openshiftAuthorizer struct {
15
-	masterAuthorizationNamespace string
16
-	ruleResolver                 rulevalidation.AuthorizationRuleResolver
15
+	ruleResolver rulevalidation.AuthorizationRuleResolver
17 16
 }
18 17
 
19
-func NewAuthorizer(masterAuthorizationNamespace string, ruleResolver rulevalidation.AuthorizationRuleResolver) Authorizer {
20
-	return &openshiftAuthorizer{masterAuthorizationNamespace, ruleResolver}
18
+func NewAuthorizer(ruleResolver rulevalidation.AuthorizationRuleResolver) Authorizer {
19
+	return &openshiftAuthorizer{ruleResolver}
21 20
 }
22 21
 
23 22
 func (a *openshiftAuthorizer) Authorize(ctx kapi.Context, passedAttributes AuthorizationAttributes) (bool, string, error) {
... ...
@@ -28,7 +27,7 @@ func (a *openshiftAuthorizer) Authorize(ctx kapi.Context, passedAttributes Autho
28 28
 	// This is most common when a bound role is missing, but enough roles are still present and bound to authorize the request.
29 29
 	errs := []error{}
30 30
 
31
-	masterContext := kapi.WithNamespace(ctx, a.masterAuthorizationNamespace)
31
+	masterContext := kapi.WithNamespace(ctx, kapi.NamespaceNone)
32 32
 	globalAllowed, globalReason, err := a.authorizeWithNamespaceRules(masterContext, attributes)
33 33
 	if globalAllowed {
34 34
 		return true, globalReason, nil
... ...
@@ -73,7 +72,7 @@ func (a *openshiftAuthorizer) Authorize(ctx kapi.Context, passedAttributes Autho
73 73
 }
74 74
 
75 75
 func (a *openshiftAuthorizer) GetAllowedSubjects(ctx kapi.Context, attributes AuthorizationAttributes) (util.StringSet, util.StringSet, error) {
76
-	masterContext := kapi.WithNamespace(ctx, a.masterAuthorizationNamespace)
76
+	masterContext := kapi.WithNamespace(ctx, kapi.NamespaceNone)
77 77
 	globalUsers, globalGroups, err := a.getAllowedSubjectsFromNamespaceBindings(masterContext, attributes)
78 78
 	if err != nil {
79 79
 		return nil, nil, err
... ...
@@ -140,6 +139,9 @@ func (a *openshiftAuthorizer) authorizeWithNamespaceRules(ctx kapi.Context, pass
140 140
 			return false, "", err
141 141
 		}
142 142
 		if matches {
143
+			if len(kapi.NamespaceValue(ctx)) == 0 {
144
+				return true, fmt.Sprintf("allowed by cluster rule: %#v", rule), nil
145
+			}
143 146
 			return true, fmt.Sprintf("allowed by rule in %v: %#v", kapi.NamespaceValue(ctx), rule), nil
144 147
 		}
145 148
 	}
... ...
@@ -11,15 +11,19 @@ import (
11 11
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
12 12
 
13 13
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
14
+	clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
15
+	clusterpolicybindingregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding"
14 16
 	testpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/test"
15 17
 	"github.com/openshift/origin/pkg/authorization/rulevalidation"
16 18
 	"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
17 19
 )
18 20
 
19 21
 type authorizeTest struct {
22
+	clusterPolicies      []authorizationapi.ClusterPolicy
20 23
 	policies             []authorizationapi.Policy
21 24
 	policyRetrievalError error
22 25
 
26
+	clusterBindings       []authorizationapi.ClusterPolicyBinding
23 27
 	bindings              []authorizationapi.PolicyBinding
24 28
 	bindingRetrievalError error
25 29
 
... ...
@@ -33,7 +37,7 @@ type authorizeTest struct {
33 33
 
34 34
 func TestResourceNameDeny(t *testing.T) {
35 35
 	test := &authorizeTest{
36
-		context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), bootstrappolicy.DefaultMasterAuthorizationNamespace), &user.DefaultInfo{Name: "just-a-user"}),
36
+		context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), kapi.NamespaceNone), &user.DefaultInfo{Name: "just-a-user"}),
37 37
 		attributes: &DefaultAuthorizationAttributes{
38 38
 			Verb:         "get",
39 39
 			Resource:     "users",
... ...
@@ -42,24 +46,24 @@ func TestResourceNameDeny(t *testing.T) {
42 42
 		expectedAllowed: false,
43 43
 		expectedReason:  `just-a-user cannot get on users with name "just-a-user"`,
44 44
 	}
45
-	test.policies = newDefaultGlobalPolicies()
46
-	test.bindings = newDefaultGlobalBinding()
45
+	test.clusterPolicies = newDefaultClusterPolicies()
46
+	test.clusterBindings = newDefaultClusterPolicyBindings()
47 47
 	test.test(t)
48 48
 }
49 49
 
50 50
 func TestResourceNameAllow(t *testing.T) {
51 51
 	test := &authorizeTest{
52
-		context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), bootstrappolicy.DefaultMasterAuthorizationNamespace), &user.DefaultInfo{Name: "just-a-user"}),
52
+		context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), kapi.NamespaceNone), &user.DefaultInfo{Name: "just-a-user"}),
53 53
 		attributes: &DefaultAuthorizationAttributes{
54 54
 			Verb:         "get",
55 55
 			Resource:     "users",
56 56
 			ResourceName: "~",
57 57
 		},
58 58
 		expectedAllowed: true,
59
-		expectedReason:  "allowed by rule in master",
59
+		expectedReason:  "allowed by cluster rule",
60 60
 	}
61
-	test.policies = newDefaultGlobalPolicies()
62
-	test.bindings = newDefaultGlobalBinding()
61
+	test.clusterPolicies = newDefaultClusterPolicies()
62
+	test.clusterBindings = newDefaultClusterPolicyBindings()
63 63
 	test.test(t)
64 64
 }
65 65
 
... ...
@@ -73,18 +77,16 @@ func TestDeniedWithError(t *testing.T) {
73 73
 		expectedAllowed: false,
74 74
 		expectedError:   "my special error",
75 75
 	}
76
-	test.policies = newDefaultGlobalPolicies()
76
+	test.clusterPolicies = newDefaultClusterPolicies()
77 77
 	test.policies = append(test.policies, newAdzePolicies()...)
78
-	test.bindings = newDefaultGlobalBinding()
78
+	test.clusterBindings = newDefaultClusterPolicyBindings()
79 79
 	test.bindings = append(test.bindings, newAdzeBindings()...)
80 80
 	test.bindings[0].RoleBindings["missing"] = authorizationapi.RoleBinding{
81 81
 		ObjectMeta: kapi.ObjectMeta{
82
-			Name:      "missing",
83
-			Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
82
+			Name: "missing",
84 83
 		},
85 84
 		RoleRef: kapi.ObjectReference{
86
-			Name:      "not-a-real-binding",
87
-			Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
85
+			Name: "not-a-real-binding",
88 86
 		},
89 87
 		Users: util.NewStringSet("Anna"),
90 88
 	}
... ...
@@ -103,18 +105,16 @@ func TestAllowedWithMissingBinding(t *testing.T) {
103 103
 		expectedAllowed: true,
104 104
 		expectedReason:  "allowed by rule in adze",
105 105
 	}
106
-	test.policies = newDefaultGlobalPolicies()
106
+	test.clusterPolicies = newDefaultClusterPolicies()
107 107
 	test.policies = append(test.policies, newAdzePolicies()...)
108
-	test.bindings = newDefaultGlobalBinding()
108
+	test.clusterBindings = newDefaultClusterPolicyBindings()
109 109
 	test.bindings = append(test.bindings, newAdzeBindings()...)
110 110
 	test.bindings[0].RoleBindings["missing"] = authorizationapi.RoleBinding{
111 111
 		ObjectMeta: kapi.ObjectMeta{
112
-			Name:      "missing",
113
-			Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
112
+			Name: "missing",
114 113
 		},
115 114
 		RoleRef: kapi.ObjectReference{
116
-			Name:      "not-a-real-binding",
117
-			Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
115
+			Name: "not-a-real-binding",
118 116
 		},
119 117
 		Users: util.NewStringSet("Anna"),
120 118
 	}
... ...
@@ -131,10 +131,10 @@ func TestHealthAllow(t *testing.T) {
131 131
 			URL:            "/healthz",
132 132
 		},
133 133
 		expectedAllowed: true,
134
-		expectedReason:  "allowed by rule in master",
134
+		expectedReason:  "allowed by cluster rule",
135 135
 	}
136
-	test.policies = newDefaultGlobalPolicies()
137
-	test.bindings = newDefaultGlobalBinding()
136
+	test.clusterPolicies = newDefaultClusterPolicies()
137
+	test.clusterBindings = newDefaultClusterPolicyBindings()
138 138
 
139 139
 	test.test(t)
140 140
 }
... ...
@@ -148,10 +148,10 @@ func TestNonResourceAllow(t *testing.T) {
148 148
 			URL:            "not-specified",
149 149
 		},
150 150
 		expectedAllowed: true,
151
-		expectedReason:  "allowed by rule in master",
151
+		expectedReason:  "allowed by cluster rule",
152 152
 	}
153
-	test.policies = newDefaultGlobalPolicies()
154
-	test.bindings = newDefaultGlobalBinding()
153
+	test.clusterPolicies = newDefaultClusterPolicies()
154
+	test.clusterBindings = newDefaultClusterPolicyBindings()
155 155
 
156 156
 	test.test(t)
157 157
 }
... ...
@@ -167,8 +167,8 @@ func TestNonResourceDeny(t *testing.T) {
167 167
 		expectedAllowed: false,
168 168
 		expectedReason:  `no-one cannot get on not-allowed`,
169 169
 	}
170
-	test.policies = newDefaultGlobalPolicies()
171
-	test.bindings = newDefaultGlobalBinding()
170
+	test.clusterPolicies = newDefaultClusterPolicies()
171
+	test.clusterBindings = newDefaultClusterPolicyBindings()
172 172
 
173 173
 	test.test(t)
174 174
 }
... ...
@@ -184,31 +184,31 @@ func TestHealthDeny(t *testing.T) {
184 184
 		expectedAllowed: false,
185 185
 		expectedReason:  `no-one cannot get on /healthz`,
186 186
 	}
187
-	test.policies = newDefaultGlobalPolicies()
188
-	test.bindings = newDefaultGlobalBinding()
187
+	test.clusterPolicies = newDefaultClusterPolicies()
188
+	test.clusterBindings = newDefaultClusterPolicyBindings()
189 189
 
190 190
 	test.test(t)
191 191
 }
192 192
 
193 193
 func TestAdminEditingGlobalDeploymentConfig(t *testing.T) {
194 194
 	test := &authorizeTest{
195
-		context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), bootstrappolicy.DefaultMasterAuthorizationNamespace), &user.DefaultInfo{Name: "ClusterAdmin"}),
195
+		context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), kapi.NamespaceNone), &user.DefaultInfo{Name: "ClusterAdmin"}),
196 196
 		attributes: &DefaultAuthorizationAttributes{
197 197
 			Verb:     "update",
198 198
 			Resource: "deploymentConfigs",
199 199
 		},
200 200
 		expectedAllowed: true,
201
-		expectedReason:  "allowed by rule in master",
201
+		expectedReason:  "allowed by cluster rule",
202 202
 	}
203
-	test.policies = newDefaultGlobalPolicies()
204
-	test.bindings = newDefaultGlobalBinding()
203
+	test.clusterPolicies = newDefaultClusterPolicies()
204
+	test.clusterBindings = newDefaultClusterPolicyBindings()
205 205
 
206 206
 	test.test(t)
207 207
 }
208 208
 
209 209
 func TestDisallowedViewingGlobalPods(t *testing.T) {
210 210
 	test := &authorizeTest{
211
-		context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), bootstrappolicy.DefaultMasterAuthorizationNamespace), &user.DefaultInfo{Name: "SomeYahoo"}),
211
+		context: kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), kapi.NamespaceNone), &user.DefaultInfo{Name: "SomeYahoo"}),
212 212
 		attributes: &DefaultAuthorizationAttributes{
213 213
 			Verb:     "get",
214 214
 			Resource: "pods",
... ...
@@ -216,8 +216,8 @@ func TestDisallowedViewingGlobalPods(t *testing.T) {
216 216
 		expectedAllowed: false,
217 217
 		expectedReason:  `SomeYahoo cannot get on pods`,
218 218
 	}
219
-	test.policies = newDefaultGlobalPolicies()
220
-	test.bindings = newDefaultGlobalBinding()
219
+	test.clusterPolicies = newDefaultClusterPolicies()
220
+	test.clusterBindings = newDefaultClusterPolicyBindings()
221 221
 
222 222
 	test.test(t)
223 223
 }
... ...
@@ -232,9 +232,9 @@ func TestProjectAdminEditPolicy(t *testing.T) {
232 232
 		expectedAllowed: true,
233 233
 		expectedReason:  "allowed by rule in adze",
234 234
 	}
235
-	test.policies = newDefaultGlobalPolicies()
235
+	test.clusterPolicies = newDefaultClusterPolicies()
236 236
 	test.policies = append(test.policies, newAdzePolicies()...)
237
-	test.bindings = newDefaultGlobalBinding()
237
+	test.clusterBindings = newDefaultClusterPolicyBindings()
238 238
 	test.bindings = append(test.bindings, newAdzeBindings()...)
239 239
 
240 240
 	test.test(t)
... ...
@@ -248,11 +248,11 @@ func TestGlobalPolicyOutranksLocalPolicy(t *testing.T) {
248 248
 			Resource: "roles",
249 249
 		},
250 250
 		expectedAllowed: true,
251
-		expectedReason:  "allowed by rule in master",
251
+		expectedReason:  "allowed by cluster rule",
252 252
 	}
253
-	test.policies = newDefaultGlobalPolicies()
253
+	test.clusterPolicies = newDefaultClusterPolicies()
254 254
 	test.policies = append(test.policies, newAdzePolicies()...)
255
-	test.bindings = newDefaultGlobalBinding()
255
+	test.clusterBindings = newDefaultClusterPolicyBindings()
256 256
 	test.bindings = append(test.bindings, newAdzeBindings()...)
257 257
 
258 258
 	test.test(t)
... ...
@@ -268,10 +268,10 @@ func TestResourceRestrictionsWork(t *testing.T) {
268 268
 		expectedAllowed: true,
269 269
 		expectedReason:  "allowed by rule in adze",
270 270
 	}
271
-	test1.policies = newDefaultGlobalPolicies()
272
-	test1.policies = append(test1.policies, newAdzePolicies()...)
273
-	test1.bindings = newDefaultGlobalBinding()
274
-	test1.bindings = append(test1.bindings, newAdzeBindings()...)
271
+	test1.clusterPolicies = newDefaultClusterPolicies()
272
+	test1.policies = newAdzePolicies()
273
+	test1.clusterBindings = newDefaultClusterPolicyBindings()
274
+	test1.bindings = newAdzeBindings()
275 275
 	test1.test(t)
276 276
 
277 277
 	test2 := &authorizeTest{
... ...
@@ -283,10 +283,10 @@ func TestResourceRestrictionsWork(t *testing.T) {
283 283
 		expectedAllowed: false,
284 284
 		expectedReason:  `Rachel cannot get on pods in adze`,
285 285
 	}
286
-	test2.policies = newDefaultGlobalPolicies()
287
-	test2.policies = append(test2.policies, newAdzePolicies()...)
288
-	test2.bindings = newDefaultGlobalBinding()
289
-	test2.bindings = append(test2.bindings, newAdzeBindings()...)
286
+	test2.clusterPolicies = newDefaultClusterPolicies()
287
+	test2.policies = newAdzePolicies()
288
+	test2.clusterBindings = newDefaultClusterPolicyBindings()
289
+	test2.bindings = newAdzeBindings()
290 290
 	test2.test(t)
291 291
 }
292 292
 
... ...
@@ -300,10 +300,10 @@ func TestResourceRestrictionsWithWeirdWork(t *testing.T) {
300 300
 		expectedAllowed: true,
301 301
 		expectedReason:  "allowed by rule in adze",
302 302
 	}
303
-	test1.policies = newDefaultGlobalPolicies()
304
-	test1.policies = append(test1.policies, newAdzePolicies()...)
305
-	test1.bindings = newDefaultGlobalBinding()
306
-	test1.bindings = append(test1.bindings, newAdzeBindings()...)
303
+	test1.clusterPolicies = newDefaultClusterPolicies()
304
+	test1.policies = newAdzePolicies()
305
+	test1.clusterBindings = newDefaultClusterPolicyBindings()
306
+	test1.bindings = newAdzeBindings()
307 307
 	test1.test(t)
308 308
 
309 309
 	test2 := &authorizeTest{
... ...
@@ -315,10 +315,10 @@ func TestResourceRestrictionsWithWeirdWork(t *testing.T) {
315 315
 		expectedAllowed: true,
316 316
 		expectedReason:  "allowed by rule in adze",
317 317
 	}
318
-	test2.policies = newDefaultGlobalPolicies()
319
-	test2.policies = append(test2.policies, newAdzePolicies()...)
320
-	test2.bindings = newDefaultGlobalBinding()
321
-	test2.bindings = append(test2.bindings, newAdzeBindings()...)
318
+	test2.clusterPolicies = newDefaultClusterPolicies()
319
+	test2.policies = newAdzePolicies()
320
+	test2.clusterBindings = newDefaultClusterPolicyBindings()
321
+	test2.bindings = newAdzeBindings()
322 322
 	test2.test(t)
323 323
 }
324 324
 
... ...
@@ -332,9 +332,9 @@ func TestLocalRightsDoNotGrantGlobalRights(t *testing.T) {
332 332
 		expectedAllowed: false,
333 333
 		expectedReason:  `Rachel cannot get on buildConfigs in backsaw`,
334 334
 	}
335
-	test.policies = newDefaultGlobalPolicies()
335
+	test.clusterPolicies = newDefaultClusterPolicies()
336 336
 	test.policies = append(test.policies, newAdzePolicies()...)
337
-	test.bindings = newDefaultGlobalBinding()
337
+	test.clusterBindings = newDefaultClusterPolicyBindings()
338 338
 	test.bindings = append(test.bindings, newAdzeBindings()...)
339 339
 
340 340
 	test.test(t)
... ...
@@ -350,10 +350,10 @@ func TestVerbRestrictionsWork(t *testing.T) {
350 350
 		expectedAllowed: true,
351 351
 		expectedReason:  "allowed by rule in adze",
352 352
 	}
353
-	test1.policies = newDefaultGlobalPolicies()
354
-	test1.policies = append(test1.policies, newAdzePolicies()...)
355
-	test1.bindings = newDefaultGlobalBinding()
356
-	test1.bindings = append(test1.bindings, newAdzeBindings()...)
353
+	test1.clusterPolicies = newDefaultClusterPolicies()
354
+	test1.policies = newAdzePolicies()
355
+	test1.clusterBindings = newDefaultClusterPolicyBindings()
356
+	test1.bindings = newAdzeBindings()
357 357
 	test1.test(t)
358 358
 
359 359
 	test2 := &authorizeTest{
... ...
@@ -365,17 +365,19 @@ func TestVerbRestrictionsWork(t *testing.T) {
365 365
 		expectedAllowed: false,
366 366
 		expectedReason:  `Valerie cannot create on buildConfigs in adze`,
367 367
 	}
368
-	test2.policies = newDefaultGlobalPolicies()
369
-	test2.policies = append(test2.policies, newAdzePolicies()...)
370
-	test2.bindings = newDefaultGlobalBinding()
371
-	test2.bindings = append(test2.bindings, newAdzeBindings()...)
368
+	test2.clusterPolicies = newDefaultClusterPolicies()
369
+	test2.policies = newAdzePolicies()
370
+	test2.clusterBindings = newDefaultClusterPolicyBindings()
371
+	test2.bindings = newAdzeBindings()
372 372
 	test2.test(t)
373 373
 }
374 374
 
375 375
 func (test *authorizeTest) test(t *testing.T) {
376 376
 	policyRegistry := testpolicyregistry.NewPolicyRegistry(test.policies, test.policyRetrievalError)
377 377
 	policyBindingRegistry := testpolicyregistry.NewPolicyBindingRegistry(test.bindings, test.bindingRetrievalError)
378
-	authorizer := NewAuthorizer(bootstrappolicy.DefaultMasterAuthorizationNamespace, rulevalidation.NewDefaultRuleResolver(policyRegistry, policyBindingRegistry))
378
+	clusterPolicyRegistry := clusterpolicyregistry.NewSimulatedRegistry(testpolicyregistry.NewClusterPolicyRegistry(test.clusterPolicies, test.policyRetrievalError))
379
+	clusterPolicyBindingRegistry := clusterpolicybindingregistry.NewSimulatedRegistry(testpolicyregistry.NewClusterPolicyBindingRegistry(test.clusterBindings, test.bindingRetrievalError))
380
+	authorizer := NewAuthorizer(rulevalidation.NewDefaultRuleResolver(policyRegistry, policyBindingRegistry, clusterPolicyRegistry, clusterPolicyBindingRegistry))
379 381
 
380 382
 	actualAllowed, actualReason, actualError := authorizer.Authorize(test.context, *test.attributes)
381 383
 
... ...
@@ -430,45 +432,40 @@ func matchError(expected string, actual error, field string, t *testing.T) {
430 430
 	}
431 431
 }
432 432
 
433
-func newDefaultGlobalPolicies() []authorizationapi.Policy {
434
-	return []authorizationapi.Policy{*GetBootstrapPolicy(bootstrappolicy.DefaultMasterAuthorizationNamespace)}
433
+func newDefaultClusterPolicies() []authorizationapi.ClusterPolicy {
434
+	return []authorizationapi.ClusterPolicy{*GetBootstrapPolicy()}
435 435
 }
436
-func newDefaultGlobalBinding() []authorizationapi.PolicyBinding {
437
-	policyBinding := authorizationapi.PolicyBinding{
436
+func newDefaultClusterPolicyBindings() []authorizationapi.ClusterPolicyBinding {
437
+	policyBinding := authorizationapi.ClusterPolicyBinding{
438 438
 		ObjectMeta: kapi.ObjectMeta{
439
-			Name:      bootstrappolicy.DefaultMasterAuthorizationNamespace,
440
-			Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
439
+			Name: authorizationapi.ClusterPolicyBindingName,
441 440
 		},
442
-		RoleBindings: map[string]authorizationapi.RoleBinding{
441
+		RoleBindings: map[string]authorizationapi.ClusterRoleBinding{
443 442
 			"extra-cluster-admins": {
444 443
 				ObjectMeta: kapi.ObjectMeta{
445
-					Name:      "cluster-admins",
446
-					Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
444
+					Name: "cluster-admins",
447 445
 				},
448 446
 				RoleRef: kapi.ObjectReference{
449
-					Name:      "cluster-admin",
450
-					Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
447
+					Name: "cluster-admin",
451 448
 				},
452 449
 				Users:  util.NewStringSet("ClusterAdmin"),
453 450
 				Groups: util.NewStringSet("RootUsers"),
454 451
 			},
455 452
 			"user-only": {
456 453
 				ObjectMeta: kapi.ObjectMeta{
457
-					Name:      "user-only",
458
-					Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
454
+					Name: "user-only",
459 455
 				},
460 456
 				RoleRef: kapi.ObjectReference{
461
-					Name:      "basic-user",
462
-					Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
457
+					Name: "basic-user",
463 458
 				},
464 459
 				Users: util.NewStringSet("just-a-user"),
465 460
 			},
466 461
 		},
467 462
 	}
468
-	for key, value := range GetBootstrapPolicyBinding(bootstrappolicy.DefaultMasterAuthorizationNamespace).RoleBindings {
463
+	for key, value := range GetBootstrapPolicyBinding().RoleBindings {
469 464
 		policyBinding.RoleBindings[key] = value
470 465
 	}
471
-	return []authorizationapi.PolicyBinding{policyBinding}
466
+	return []authorizationapi.ClusterPolicyBinding{policyBinding}
472 467
 }
473 468
 
474 469
 func newAdzePolicies() []authorizationapi.Policy {
... ...
@@ -497,7 +494,7 @@ func newAdzeBindings() []authorizationapi.PolicyBinding {
497 497
 	return []authorizationapi.PolicyBinding{
498 498
 		{
499 499
 			ObjectMeta: kapi.ObjectMeta{
500
-				Name:      bootstrappolicy.DefaultMasterAuthorizationNamespace,
500
+				Name:      authorizationapi.ClusterPolicyBindingName,
501 501
 				Namespace: "adze",
502 502
 			},
503 503
 			RoleBindings: map[string]authorizationapi.RoleBinding{
... ...
@@ -507,8 +504,7 @@ func newAdzeBindings() []authorizationapi.PolicyBinding {
507 507
 						Namespace: "adze",
508 508
 					},
509 509
 					RoleRef: kapi.ObjectReference{
510
-						Name:      bootstrappolicy.AdminRoleName,
511
-						Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
510
+						Name: bootstrappolicy.AdminRoleName,
512 511
 					},
513 512
 					Users: util.NewStringSet("Anna"),
514 513
 				},
... ...
@@ -518,8 +514,7 @@ func newAdzeBindings() []authorizationapi.PolicyBinding {
518 518
 						Namespace: "adze",
519 519
 					},
520 520
 					RoleRef: kapi.ObjectReference{
521
-						Name:      bootstrappolicy.ViewRoleName,
522
-						Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
521
+						Name: bootstrappolicy.ViewRoleName,
523 522
 					},
524 523
 					Users: util.NewStringSet("Valerie"),
525 524
 				},
... ...
@@ -529,8 +524,7 @@ func newAdzeBindings() []authorizationapi.PolicyBinding {
529 529
 						Namespace: "adze",
530 530
 					},
531 531
 					RoleRef: kapi.ObjectReference{
532
-						Name:      bootstrappolicy.EditRoleName,
533
-						Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
532
+						Name: bootstrappolicy.EditRoleName,
534 533
 					},
535 534
 					Users: util.NewStringSet("Ellen"),
536 535
 				},
... ...
@@ -538,7 +532,7 @@ func newAdzeBindings() []authorizationapi.PolicyBinding {
538 538
 		},
539 539
 		{
540 540
 			ObjectMeta: kapi.ObjectMeta{
541
-				Name:      "adze",
541
+				Name:      authorizationapi.GetPolicyBindingName("adze"),
542 542
 				Namespace: "adze",
543 543
 			},
544 544
 			RoleBindings: map[string]authorizationapi.RoleBinding{
... ...
@@ -23,10 +23,10 @@ func TestInvalidRole(t *testing.T) {
23 23
 		expectedAllowed: false,
24 24
 		expectedError:   "unable to interpret:",
25 25
 	}
26
-	test.policies = newDefaultGlobalPolicies()
27
-	test.policies = append(test.policies, newInvalidExtensionPolicies()...)
28
-	test.bindings = newDefaultGlobalBinding()
29
-	test.bindings = append(test.bindings, newInvalidExtensionBindings()...)
26
+	test.clusterPolicies = newDefaultClusterPolicies()
27
+	test.policies = newInvalidExtensionPolicies()
28
+	test.clusterBindings = newDefaultClusterPolicyBindings()
29
+	test.bindings = newInvalidExtensionBindings()
30 30
 
31 31
 	test.test(t)
32 32
 }
... ...
@@ -40,10 +40,10 @@ func TestInvalidRoleButRuleNotUsed(t *testing.T) {
40 40
 		expectedAllowed: true,
41 41
 		expectedReason:  "allowed by rule in mallet",
42 42
 	}
43
-	test.policies = newDefaultGlobalPolicies()
44
-	test.policies = append(test.policies, newInvalidExtensionPolicies()...)
45
-	test.bindings = newDefaultGlobalBinding()
46
-	test.bindings = append(test.bindings, newInvalidExtensionBindings()...)
43
+	test.clusterPolicies = newDefaultClusterPolicies()
44
+	test.policies = newInvalidExtensionPolicies()
45
+	test.clusterBindings = newDefaultClusterPolicyBindings()
46
+	test.bindings = newInvalidExtensionBindings()
47 47
 
48 48
 	test.test(t)
49 49
 }
... ...
@@ -57,11 +57,11 @@ func TestViewerGetAllowedKindInMallet(t *testing.T) {
57 57
 		expectedAllowed: true,
58 58
 		expectedReason:  "allowed by rule in mallet",
59 59
 	}
60
-	test.policies = newDefaultGlobalPolicies()
61
-	test.policies = append(test.policies, newAdzePolicies()...)
60
+	test.clusterPolicies = newDefaultClusterPolicies()
61
+	test.policies = newAdzePolicies()
62 62
 	test.policies = append(test.policies, newMalletPolicies()...)
63
-	test.bindings = newDefaultGlobalBinding()
64
-	test.bindings = append(test.bindings, newAdzeBindings()...)
63
+	test.clusterBindings = newDefaultClusterPolicyBindings()
64
+	test.bindings = newAdzeBindings()
65 65
 	test.bindings = append(test.bindings, newMalletBindings()...)
66 66
 
67 67
 	test.test(t)
... ...
@@ -76,11 +76,11 @@ func TestViewerGetAllowedKindInAdze(t *testing.T) {
76 76
 		expectedAllowed: false,
77 77
 		expectedReason:  "Victor cannot get on pods in adze",
78 78
 	}
79
-	test.policies = newDefaultGlobalPolicies()
80
-	test.policies = append(test.policies, newAdzePolicies()...)
79
+	test.clusterPolicies = newDefaultClusterPolicies()
80
+	test.policies = newAdzePolicies()
81 81
 	test.policies = append(test.policies, newMalletPolicies()...)
82
-	test.bindings = newDefaultGlobalBinding()
83
-	test.bindings = append(test.bindings, newAdzeBindings()...)
82
+	test.clusterBindings = newDefaultClusterPolicyBindings()
83
+	test.bindings = newAdzeBindings()
84 84
 	test.bindings = append(test.bindings, newMalletBindings()...)
85 85
 
86 86
 	test.test(t)
... ...
@@ -96,11 +96,11 @@ func TestViewerGetDisallowedKindInMallet(t *testing.T) {
96 96
 		expectedAllowed: false,
97 97
 		expectedReason:  "Victor cannot get on policies in mallet",
98 98
 	}
99
-	test.policies = newDefaultGlobalPolicies()
100
-	test.policies = append(test.policies, newAdzePolicies()...)
99
+	test.clusterPolicies = newDefaultClusterPolicies()
100
+	test.policies = newAdzePolicies()
101 101
 	test.policies = append(test.policies, newMalletPolicies()...)
102
-	test.bindings = newDefaultGlobalBinding()
103
-	test.bindings = append(test.bindings, newAdzeBindings()...)
102
+	test.clusterBindings = newDefaultClusterPolicyBindings()
103
+	test.bindings = newAdzeBindings()
104 104
 	test.bindings = append(test.bindings, newMalletBindings()...)
105 105
 
106 106
 	test.test(t)
... ...
@@ -115,11 +115,11 @@ func TestViewerGetDisallowedKindInAdze(t *testing.T) {
115 115
 		expectedAllowed: false,
116 116
 		expectedReason:  "Victor cannot get on policies in adze",
117 117
 	}
118
-	test.policies = newDefaultGlobalPolicies()
119
-	test.policies = append(test.policies, newAdzePolicies()...)
118
+	test.clusterPolicies = newDefaultClusterPolicies()
119
+	test.policies = newAdzePolicies()
120 120
 	test.policies = append(test.policies, newMalletPolicies()...)
121
-	test.bindings = newDefaultGlobalBinding()
122
-	test.bindings = append(test.bindings, newAdzeBindings()...)
121
+	test.clusterBindings = newDefaultClusterPolicyBindings()
122
+	test.bindings = newAdzeBindings()
123 123
 	test.bindings = append(test.bindings, newMalletBindings()...)
124 124
 
125 125
 	test.test(t)
... ...
@@ -135,11 +135,11 @@ func TestViewerCreateAllowedKindInMallet(t *testing.T) {
135 135
 		expectedAllowed: false,
136 136
 		expectedReason:  "Victor cannot create on pods in mallet",
137 137
 	}
138
-	test.policies = newDefaultGlobalPolicies()
139
-	test.policies = append(test.policies, newAdzePolicies()...)
138
+	test.clusterPolicies = newDefaultClusterPolicies()
139
+	test.policies = newAdzePolicies()
140 140
 	test.policies = append(test.policies, newMalletPolicies()...)
141
-	test.bindings = newDefaultGlobalBinding()
142
-	test.bindings = append(test.bindings, newAdzeBindings()...)
141
+	test.clusterBindings = newDefaultClusterPolicyBindings()
142
+	test.bindings = newAdzeBindings()
143 143
 	test.bindings = append(test.bindings, newMalletBindings()...)
144 144
 
145 145
 	test.test(t)
... ...
@@ -154,11 +154,11 @@ func TestViewerCreateAllowedKindInAdze(t *testing.T) {
154 154
 		expectedAllowed: false,
155 155
 		expectedReason:  "Victor cannot create on pods in adze",
156 156
 	}
157
-	test.policies = newDefaultGlobalPolicies()
158
-	test.policies = append(test.policies, newAdzePolicies()...)
157
+	test.clusterPolicies = newDefaultClusterPolicies()
158
+	test.policies = newAdzePolicies()
159 159
 	test.policies = append(test.policies, newMalletPolicies()...)
160
-	test.bindings = newDefaultGlobalBinding()
161
-	test.bindings = append(test.bindings, newAdzeBindings()...)
160
+	test.clusterBindings = newDefaultClusterPolicyBindings()
161
+	test.bindings = newAdzeBindings()
162 162
 	test.bindings = append(test.bindings, newMalletBindings()...)
163 163
 
164 164
 	test.test(t)
... ...
@@ -174,11 +174,11 @@ func TestEditorUpdateAllowedKindInMallet(t *testing.T) {
174 174
 		expectedAllowed: true,
175 175
 		expectedReason:  "allowed by rule in mallet",
176 176
 	}
177
-	test.policies = newDefaultGlobalPolicies()
178
-	test.policies = append(test.policies, newAdzePolicies()...)
177
+	test.clusterPolicies = newDefaultClusterPolicies()
178
+	test.policies = newAdzePolicies()
179 179
 	test.policies = append(test.policies, newMalletPolicies()...)
180
-	test.bindings = newDefaultGlobalBinding()
181
-	test.bindings = append(test.bindings, newAdzeBindings()...)
180
+	test.clusterBindings = newDefaultClusterPolicyBindings()
181
+	test.bindings = newAdzeBindings()
182 182
 	test.bindings = append(test.bindings, newMalletBindings()...)
183 183
 
184 184
 	test.test(t)
... ...
@@ -193,11 +193,11 @@ func TestEditorUpdateAllowedKindInAdze(t *testing.T) {
193 193
 		expectedAllowed: false,
194 194
 		expectedReason:  "Edgar cannot update on pods in adze",
195 195
 	}
196
-	test.policies = newDefaultGlobalPolicies()
197
-	test.policies = append(test.policies, newAdzePolicies()...)
196
+	test.clusterPolicies = newDefaultClusterPolicies()
197
+	test.policies = newAdzePolicies()
198 198
 	test.policies = append(test.policies, newMalletPolicies()...)
199
-	test.bindings = newDefaultGlobalBinding()
200
-	test.bindings = append(test.bindings, newAdzeBindings()...)
199
+	test.clusterBindings = newDefaultClusterPolicyBindings()
200
+	test.bindings = newAdzeBindings()
201 201
 	test.bindings = append(test.bindings, newMalletBindings()...)
202 202
 
203 203
 	test.test(t)
... ...
@@ -213,11 +213,11 @@ func TestEditorUpdateDisallowedKindInMallet(t *testing.T) {
213 213
 		expectedAllowed: false,
214 214
 		expectedReason:  "Edgar cannot update on roleBindings in mallet",
215 215
 	}
216
-	test.policies = newDefaultGlobalPolicies()
217
-	test.policies = append(test.policies, newAdzePolicies()...)
216
+	test.clusterPolicies = newDefaultClusterPolicies()
217
+	test.policies = newAdzePolicies()
218 218
 	test.policies = append(test.policies, newMalletPolicies()...)
219
-	test.bindings = newDefaultGlobalBinding()
220
-	test.bindings = append(test.bindings, newAdzeBindings()...)
219
+	test.clusterBindings = newDefaultClusterPolicyBindings()
220
+	test.bindings = newAdzeBindings()
221 221
 	test.bindings = append(test.bindings, newMalletBindings()...)
222 222
 
223 223
 	test.test(t)
... ...
@@ -232,11 +232,11 @@ func TestEditorUpdateDisallowedKindInAdze(t *testing.T) {
232 232
 		expectedAllowed: false,
233 233
 		expectedReason:  "Edgar cannot update on roleBindings in adze",
234 234
 	}
235
-	test.policies = newDefaultGlobalPolicies()
236
-	test.policies = append(test.policies, newAdzePolicies()...)
235
+	test.clusterPolicies = newDefaultClusterPolicies()
236
+	test.policies = newAdzePolicies()
237 237
 	test.policies = append(test.policies, newMalletPolicies()...)
238
-	test.bindings = newDefaultGlobalBinding()
239
-	test.bindings = append(test.bindings, newAdzeBindings()...)
238
+	test.clusterBindings = newDefaultClusterPolicyBindings()
239
+	test.bindings = newAdzeBindings()
240 240
 	test.bindings = append(test.bindings, newMalletBindings()...)
241 241
 
242 242
 	test.test(t)
... ...
@@ -252,11 +252,11 @@ func TestEditorGetAllowedKindInMallet(t *testing.T) {
252 252
 		expectedAllowed: true,
253 253
 		expectedReason:  "allowed by rule in mallet",
254 254
 	}
255
-	test.policies = newDefaultGlobalPolicies()
256
-	test.policies = append(test.policies, newAdzePolicies()...)
255
+	test.clusterPolicies = newDefaultClusterPolicies()
256
+	test.policies = newAdzePolicies()
257 257
 	test.policies = append(test.policies, newMalletPolicies()...)
258
-	test.bindings = newDefaultGlobalBinding()
259
-	test.bindings = append(test.bindings, newAdzeBindings()...)
258
+	test.clusterBindings = newDefaultClusterPolicyBindings()
259
+	test.bindings = newAdzeBindings()
260 260
 	test.bindings = append(test.bindings, newMalletBindings()...)
261 261
 
262 262
 	test.test(t)
... ...
@@ -271,11 +271,11 @@ func TestEditorGetAllowedKindInAdze(t *testing.T) {
271 271
 		expectedAllowed: false,
272 272
 		expectedReason:  "Edgar cannot get on pods in adze",
273 273
 	}
274
-	test.policies = newDefaultGlobalPolicies()
275
-	test.policies = append(test.policies, newAdzePolicies()...)
274
+	test.clusterPolicies = newDefaultClusterPolicies()
275
+	test.policies = newAdzePolicies()
276 276
 	test.policies = append(test.policies, newMalletPolicies()...)
277
-	test.bindings = newDefaultGlobalBinding()
278
-	test.bindings = append(test.bindings, newAdzeBindings()...)
277
+	test.clusterBindings = newDefaultClusterPolicyBindings()
278
+	test.bindings = newAdzeBindings()
279 279
 	test.bindings = append(test.bindings, newMalletBindings()...)
280 280
 
281 281
 	test.test(t)
... ...
@@ -291,11 +291,11 @@ func TestAdminUpdateAllowedKindInMallet(t *testing.T) {
291 291
 		expectedAllowed: true,
292 292
 		expectedReason:  "allowed by rule in mallet",
293 293
 	}
294
-	test.policies = newDefaultGlobalPolicies()
295
-	test.policies = append(test.policies, newAdzePolicies()...)
294
+	test.clusterPolicies = newDefaultClusterPolicies()
295
+	test.policies = newAdzePolicies()
296 296
 	test.policies = append(test.policies, newMalletPolicies()...)
297
-	test.bindings = newDefaultGlobalBinding()
298
-	test.bindings = append(test.bindings, newAdzeBindings()...)
297
+	test.clusterBindings = newDefaultClusterPolicyBindings()
298
+	test.bindings = newAdzeBindings()
299 299
 	test.bindings = append(test.bindings, newMalletBindings()...)
300 300
 
301 301
 	test.test(t)
... ...
@@ -310,11 +310,11 @@ func TestAdminUpdateAllowedKindInAdze(t *testing.T) {
310 310
 		expectedAllowed: false,
311 311
 		expectedReason:  "Matthew cannot update on roleBindings in adze",
312 312
 	}
313
-	test.policies = newDefaultGlobalPolicies()
314
-	test.policies = append(test.policies, newAdzePolicies()...)
313
+	test.clusterPolicies = newDefaultClusterPolicies()
314
+	test.policies = newAdzePolicies()
315 315
 	test.policies = append(test.policies, newMalletPolicies()...)
316
-	test.bindings = newDefaultGlobalBinding()
317
-	test.bindings = append(test.bindings, newAdzeBindings()...)
316
+	test.clusterBindings = newDefaultClusterPolicyBindings()
317
+	test.bindings = newAdzeBindings()
318 318
 	test.bindings = append(test.bindings, newMalletBindings()...)
319 319
 
320 320
 	test.test(t)
... ...
@@ -330,11 +330,11 @@ func TestAdminUpdateStatusInMallet(t *testing.T) {
330 330
 		expectedAllowed: false,
331 331
 		expectedReason:  "Matthew cannot update on pods/status in mallet",
332 332
 	}
333
-	test.policies = newDefaultGlobalPolicies()
334
-	test.policies = append(test.policies, newAdzePolicies()...)
333
+	test.clusterPolicies = newDefaultClusterPolicies()
334
+	test.policies = newAdzePolicies()
335 335
 	test.policies = append(test.policies, newMalletPolicies()...)
336
-	test.bindings = newDefaultGlobalBinding()
337
-	test.bindings = append(test.bindings, newAdzeBindings()...)
336
+	test.clusterBindings = newDefaultClusterPolicyBindings()
337
+	test.bindings = newAdzeBindings()
338 338
 	test.bindings = append(test.bindings, newMalletBindings()...)
339 339
 
340 340
 	test.test(t)
... ...
@@ -349,11 +349,11 @@ func TestAdminGetStatusInMallet(t *testing.T) {
349 349
 		expectedAllowed: true,
350 350
 		expectedReason:  "allowed by rule in mallet",
351 351
 	}
352
-	test.policies = newDefaultGlobalPolicies()
353
-	test.policies = append(test.policies, newAdzePolicies()...)
352
+	test.clusterPolicies = newDefaultClusterPolicies()
353
+	test.policies = newAdzePolicies()
354 354
 	test.policies = append(test.policies, newMalletPolicies()...)
355
-	test.bindings = newDefaultGlobalBinding()
356
-	test.bindings = append(test.bindings, newAdzeBindings()...)
355
+	test.clusterBindings = newDefaultClusterPolicyBindings()
356
+	test.bindings = newAdzeBindings()
357 357
 	test.bindings = append(test.bindings, newMalletBindings()...)
358 358
 
359 359
 	test.test(t)
... ...
@@ -369,11 +369,11 @@ func TestAdminUpdateDisallowedKindInMallet(t *testing.T) {
369 369
 		expectedAllowed: false,
370 370
 		expectedReason:  "Matthew cannot update on policies in mallet",
371 371
 	}
372
-	test.policies = newDefaultGlobalPolicies()
373
-	test.policies = append(test.policies, newAdzePolicies()...)
372
+	test.clusterPolicies = newDefaultClusterPolicies()
373
+	test.policies = newAdzePolicies()
374 374
 	test.policies = append(test.policies, newMalletPolicies()...)
375
-	test.bindings = newDefaultGlobalBinding()
376
-	test.bindings = append(test.bindings, newAdzeBindings()...)
375
+	test.clusterBindings = newDefaultClusterPolicyBindings()
376
+	test.bindings = newAdzeBindings()
377 377
 	test.bindings = append(test.bindings, newMalletBindings()...)
378 378
 
379 379
 	test.test(t)
... ...
@@ -388,11 +388,11 @@ func TestAdminUpdateDisallowedKindInAdze(t *testing.T) {
388 388
 		expectedAllowed: false,
389 389
 		expectedReason:  "Matthew cannot update on roles in adze",
390 390
 	}
391
-	test.policies = newDefaultGlobalPolicies()
392
-	test.policies = append(test.policies, newAdzePolicies()...)
391
+	test.clusterPolicies = newDefaultClusterPolicies()
392
+	test.policies = newAdzePolicies()
393 393
 	test.policies = append(test.policies, newMalletPolicies()...)
394
-	test.bindings = newDefaultGlobalBinding()
395
-	test.bindings = append(test.bindings, newAdzeBindings()...)
394
+	test.clusterBindings = newDefaultClusterPolicyBindings()
395
+	test.bindings = newAdzeBindings()
396 396
 	test.bindings = append(test.bindings, newMalletBindings()...)
397 397
 
398 398
 	test.test(t)
... ...
@@ -408,11 +408,11 @@ func TestAdminGetAllowedKindInMallet(t *testing.T) {
408 408
 		expectedAllowed: true,
409 409
 		expectedReason:  "allowed by rule in mallet",
410 410
 	}
411
-	test.policies = newDefaultGlobalPolicies()
412
-	test.policies = append(test.policies, newAdzePolicies()...)
411
+	test.clusterPolicies = newDefaultClusterPolicies()
412
+	test.policies = newAdzePolicies()
413 413
 	test.policies = append(test.policies, newMalletPolicies()...)
414
-	test.bindings = newDefaultGlobalBinding()
415
-	test.bindings = append(test.bindings, newAdzeBindings()...)
414
+	test.clusterBindings = newDefaultClusterPolicyBindings()
415
+	test.bindings = newAdzeBindings()
416 416
 	test.bindings = append(test.bindings, newMalletBindings()...)
417 417
 
418 418
 	test.test(t)
... ...
@@ -427,11 +427,11 @@ func TestAdminGetAllowedKindInAdze(t *testing.T) {
427 427
 		expectedAllowed: false,
428 428
 		expectedReason:  "Matthew cannot get on policies in adze",
429 429
 	}
430
-	test.policies = newDefaultGlobalPolicies()
431
-	test.policies = append(test.policies, newAdzePolicies()...)
430
+	test.clusterPolicies = newDefaultClusterPolicies()
431
+	test.policies = newAdzePolicies()
432 432
 	test.policies = append(test.policies, newMalletPolicies()...)
433
-	test.bindings = newDefaultGlobalBinding()
434
-	test.bindings = append(test.bindings, newAdzeBindings()...)
433
+	test.clusterBindings = newDefaultClusterPolicyBindings()
434
+	test.bindings = newAdzeBindings()
435 435
 	test.bindings = append(test.bindings, newMalletBindings()...)
436 436
 
437 437
 	test.test(t)
... ...
@@ -451,7 +451,7 @@ func newMalletBindings() []authorizationapi.PolicyBinding {
451 451
 	return []authorizationapi.PolicyBinding{
452 452
 		{
453 453
 			ObjectMeta: kapi.ObjectMeta{
454
-				Name:      bootstrappolicy.DefaultMasterAuthorizationNamespace,
454
+				Name:      authorizationapi.ClusterPolicyBindingName,
455 455
 				Namespace: "mallet",
456 456
 			},
457 457
 			RoleBindings: map[string]authorizationapi.RoleBinding{
... ...
@@ -461,8 +461,7 @@ func newMalletBindings() []authorizationapi.PolicyBinding {
461 461
 						Namespace: "mallet",
462 462
 					},
463 463
 					RoleRef: kapi.ObjectReference{
464
-						Name:      bootstrappolicy.AdminRoleName,
465
-						Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
464
+						Name: bootstrappolicy.AdminRoleName,
466 465
 					},
467 466
 					Users: util.NewStringSet("Matthew"),
468 467
 				},
... ...
@@ -472,8 +471,7 @@ func newMalletBindings() []authorizationapi.PolicyBinding {
472 472
 						Namespace: "mallet",
473 473
 					},
474 474
 					RoleRef: kapi.ObjectReference{
475
-						Name:      bootstrappolicy.ViewRoleName,
476
-						Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
475
+						Name: bootstrappolicy.ViewRoleName,
477 476
 					},
478 477
 					Users: util.NewStringSet("Victor"),
479 478
 				},
... ...
@@ -483,8 +481,7 @@ func newMalletBindings() []authorizationapi.PolicyBinding {
483 483
 						Namespace: "mallet",
484 484
 					},
485 485
 					RoleRef: kapi.ObjectReference{
486
-						Name:      bootstrappolicy.EditRoleName,
487
-						Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
486
+						Name: bootstrappolicy.EditRoleName,
488 487
 					},
489 488
 					Users: util.NewStringSet("Edgar"),
490 489
 				},
... ...
@@ -544,39 +541,36 @@ func newInvalidExtensionBindings() []authorizationapi.PolicyBinding {
544 544
 	}
545 545
 }
546 546
 
547
-func GetBootstrapPolicy(masterNamespace string) *authorizationapi.Policy {
548
-	policy := &authorizationapi.Policy{
547
+func GetBootstrapPolicy() *authorizationapi.ClusterPolicy {
548
+	policy := &authorizationapi.ClusterPolicy{
549 549
 		ObjectMeta: kapi.ObjectMeta{
550 550
 			Name:              authorizationapi.PolicyName,
551
-			Namespace:         masterNamespace,
552 551
 			CreationTimestamp: util.Now(),
553 552
 			UID:               util.NewUUID(),
554 553
 		},
555 554
 		LastModified: util.Now(),
556
-		Roles:        make(map[string]authorizationapi.Role),
555
+		Roles:        make(map[string]authorizationapi.ClusterRole),
557 556
 	}
558 557
 
559
-	for _, role := range bootstrappolicy.GetBootstrapMasterRoles(masterNamespace) {
558
+	for _, role := range bootstrappolicy.GetBootstrapClusterRoles() {
560 559
 		policy.Roles[role.Name] = role
561 560
 	}
562 561
 
563 562
 	return policy
564 563
 }
565 564
 
566
-func GetBootstrapPolicyBinding(masterNamespace string) *authorizationapi.PolicyBinding {
567
-	policyBinding := &authorizationapi.PolicyBinding{
565
+func GetBootstrapPolicyBinding() *authorizationapi.ClusterPolicyBinding {
566
+	policyBinding := &authorizationapi.ClusterPolicyBinding{
568 567
 		ObjectMeta: kapi.ObjectMeta{
569
-			Name:              masterNamespace,
570
-			Namespace:         masterNamespace,
568
+			Name:              ":Default",
571 569
 			CreationTimestamp: util.Now(),
572 570
 			UID:               util.NewUUID(),
573 571
 		},
574 572
 		LastModified: util.Now(),
575
-		PolicyRef:    kapi.ObjectReference{Namespace: masterNamespace},
576
-		RoleBindings: make(map[string]authorizationapi.RoleBinding),
573
+		RoleBindings: make(map[string]authorizationapi.ClusterRoleBinding),
577 574
 	}
578 575
 
579
-	for _, roleBinding := range bootstrappolicy.GetBootstrapMasterRoleBindings(masterNamespace) {
576
+	for _, roleBinding := range bootstrappolicy.GetBootstrapClusterRoleBindings() {
580 577
 		policyBinding.RoleBindings[roleBinding.Name] = roleBinding
581 578
 	}
582 579
 
... ...
@@ -7,14 +7,17 @@ import (
7 7
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
8 8
 
9 9
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
10
+	clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
11
+	clusterpolicybindingregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding"
10 12
 	testpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/test"
11 13
 	"github.com/openshift/origin/pkg/authorization/rulevalidation"
12
-	"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
13 14
 )
14 15
 
15 16
 type subjectsTest struct {
16 17
 	policies              []authorizationapi.Policy
17 18
 	bindings              []authorizationapi.PolicyBinding
19
+	clusterPolicies       []authorizationapi.ClusterPolicy
20
+	clusterBindings       []authorizationapi.ClusterPolicyBinding
18 21
 	policyRetrievalError  error
19 22
 	bindingRetrievalError error
20 23
 
... ...
@@ -36,10 +39,10 @@ func TestSubjects(t *testing.T) {
36 36
 		expectedUsers:  util.NewStringSet("Anna", "ClusterAdmin", "Ellen", "Valerie", "system:kube-client", "system:openshift-client", "system:openshift-deployer"),
37 37
 		expectedGroups: util.NewStringSet("RootUsers", "system:cluster-admins", "system:nodes"),
38 38
 	}
39
-	test.policies = newDefaultGlobalPolicies()
40
-	test.policies = append(test.policies, newAdzePolicies()...)
41
-	test.bindings = newDefaultGlobalBinding()
42
-	test.bindings = append(test.bindings, newAdzeBindings()...)
39
+	test.clusterPolicies = newDefaultClusterPolicies()
40
+	test.policies = newAdzePolicies()
41
+	test.clusterBindings = newDefaultClusterPolicyBindings()
42
+	test.bindings = newAdzeBindings()
43 43
 
44 44
 	test.test(t)
45 45
 }
... ...
@@ -47,7 +50,10 @@ func TestSubjects(t *testing.T) {
47 47
 func (test *subjectsTest) test(t *testing.T) {
48 48
 	policyRegistry := testpolicyregistry.NewPolicyRegistry(test.policies, test.policyRetrievalError)
49 49
 	policyBindingRegistry := testpolicyregistry.NewPolicyBindingRegistry(test.bindings, test.bindingRetrievalError)
50
-	authorizer := NewAuthorizer(bootstrappolicy.DefaultMasterAuthorizationNamespace, rulevalidation.NewDefaultRuleResolver(policyRegistry, policyBindingRegistry))
50
+	clusterPolicyRegistry := clusterpolicyregistry.NewSimulatedRegistry(testpolicyregistry.NewClusterPolicyRegistry(test.clusterPolicies, test.policyRetrievalError))
51
+	clusterPolicyBindingRegistry := clusterpolicybindingregistry.NewSimulatedRegistry(testpolicyregistry.NewClusterPolicyBindingRegistry(test.clusterBindings, test.bindingRetrievalError))
52
+
53
+	authorizer := NewAuthorizer(rulevalidation.NewDefaultRuleResolver(policyRegistry, policyBindingRegistry, clusterPolicyRegistry, clusterPolicyBindingRegistry))
51 54
 
52 55
 	actualUsers, actualGroups, actualError := authorizer.GetAllowedSubjects(test.context, *test.attributes)
53 56
 
... ...
@@ -1,7 +1,6 @@
1 1
 package cache
2 2
 
3 3
 import (
4
-	"errors"
5 4
 	"fmt"
6 5
 	"time"
7 6
 
... ...
@@ -13,17 +12,23 @@ import (
13 13
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
14 14
 
15 15
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
16
+	clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
17
+	clusterbindingregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding"
16 18
 	policyregistry "github.com/openshift/origin/pkg/authorization/registry/policy"
17 19
 	bindingregistry "github.com/openshift/origin/pkg/authorization/registry/policybinding"
18 20
 )
19 21
 
20 22
 // PolicyCache maintains a cache of PolicyRules
21 23
 type PolicyCache struct {
22
-	policyBindingIndexer cache.Indexer
23
-	policyIndexer        cache.Indexer
24
+	policyBindingIndexer        cache.Indexer
25
+	policyIndexer               cache.Indexer
26
+	clusterPolicyBindingIndexer cache.Indexer
27
+	clusterPolicyIndexer        cache.Indexer
24 28
 
25
-	bindingRegistry bindingregistry.Registry
26
-	policyRegistry  policyregistry.Registry
29
+	bindingRegistry        bindingregistry.WatchingRegistry
30
+	policyRegistry         policyregistry.WatchingRegistry
31
+	clusterBindingRegistry clusterbindingregistry.WatchingRegistry
32
+	clusterPolicyRegistry  clusterpolicyregistry.WatchingRegistry
27 33
 
28 34
 	keyFunc cache.KeyFunc
29 35
 }
... ...
@@ -45,37 +50,45 @@ func (lw *listWatch) Watch(resourceVersion string) (watch.Interface, error) {
45 45
 }
46 46
 
47 47
 // NewPolicyCache creates a new PolicyCache.  You cannot use a normal client, because you don't want policy guarding the policy from the authorizer
48
-func NewPolicyCache(bindingRegistry bindingregistry.Registry, policyRegistry policyregistry.Registry) *PolicyCache {
48
+func NewPolicyCache(bindingRegistry bindingregistry.WatchingRegistry, policyRegistry policyregistry.WatchingRegistry, clusterBindingRegistry clusterbindingregistry.WatchingRegistry, clusterPolicyRegistry clusterpolicyregistry.WatchingRegistry) *PolicyCache {
49 49
 	result := &PolicyCache{
50
-		policyIndexer:        cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}),
51
-		policyBindingIndexer: cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}),
50
+		policyIndexer:               cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}),
51
+		policyBindingIndexer:        cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}),
52
+		clusterPolicyIndexer:        cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}),
53
+		clusterPolicyBindingIndexer: cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}),
52 54
 
53 55
 		keyFunc: cache.MetaNamespaceKeyFunc,
54 56
 
55
-		bindingRegistry: bindingRegistry,
56
-		policyRegistry:  policyRegistry,
57
+		bindingRegistry:        bindingRegistry,
58
+		policyRegistry:         policyRegistry,
59
+		clusterBindingRegistry: clusterBindingRegistry,
60
+		clusterPolicyRegistry:  clusterPolicyRegistry,
57 61
 	}
58 62
 	return result
59 63
 }
60 64
 
61 65
 // Run begins watching and synchronizing the cache
62 66
 func (c *PolicyCache) Run() {
63
-	policyBindingReflector, policyReflector := c.configureReflectors()
67
+	policyBindingReflector, policyReflector, clusterPolicyBindingReflector, clusterPolicyReflector := c.configureReflectors()
64 68
 
65 69
 	policyBindingReflector.Run()
66 70
 	policyReflector.Run()
71
+	clusterPolicyBindingReflector.Run()
72
+	clusterPolicyReflector.Run()
67 73
 }
68 74
 
69 75
 // RunUntil starts a watch and handles watch events. Will restart the watch if it is closed.
70 76
 // RunUntil starts a goroutine and returns immediately. It will exit when stopCh is closed.
71 77
 func (c *PolicyCache) RunUntil(bindingStopCh <-chan struct{}, policyStopCh <-chan struct{}) {
72
-	policyBindingReflector, policyReflector := c.configureReflectors()
78
+	policyBindingReflector, policyReflector, clusterPolicyBindingReflector, clusterPolicyReflector := c.configureReflectors()
73 79
 
74 80
 	policyBindingReflector.RunUntil(bindingStopCh)
75 81
 	policyReflector.RunUntil(policyStopCh)
82
+	clusterPolicyBindingReflector.RunUntil(bindingStopCh)
83
+	clusterPolicyReflector.RunUntil(policyStopCh)
76 84
 }
77 85
 
78
-func (c *PolicyCache) configureReflectors() (*cache.Reflector, *cache.Reflector) {
86
+func (c *PolicyCache) configureReflectors() (*cache.Reflector, *cache.Reflector, *cache.Reflector, *cache.Reflector) {
79 87
 	ctx := kapi.WithNamespace(kapi.NewContext(), kapi.NamespaceAll)
80 88
 
81 89
 	policyBindingReflector := cache.NewReflector(
... ...
@@ -106,48 +119,105 @@ func (c *PolicyCache) configureReflectors() (*cache.Reflector, *cache.Reflector)
106 106
 		2*time.Minute,
107 107
 	)
108 108
 
109
-	return policyBindingReflector, policyReflector
109
+	clusterPolicyBindingReflector := cache.NewReflector(
110
+		&listWatch{
111
+			listFunc: func() (runtime.Object, error) {
112
+				return c.clusterBindingRegistry.ListClusterPolicyBindings(ctx, labels.Everything(), fields.Everything())
113
+			},
114
+			watchFunc: func(resourceVersion string) (watch.Interface, error) {
115
+				return c.clusterBindingRegistry.WatchClusterPolicyBindings(ctx, labels.Everything(), fields.Everything(), resourceVersion)
116
+			},
117
+		},
118
+		&authorizationapi.ClusterPolicyBinding{},
119
+		c.clusterPolicyBindingIndexer,
120
+		2*time.Minute,
121
+	)
122
+
123
+	clusterPolicyReflector := cache.NewReflector(
124
+		&listWatch{
125
+			listFunc: func() (runtime.Object, error) {
126
+				return c.clusterPolicyRegistry.ListClusterPolicies(ctx, labels.Everything(), fields.Everything())
127
+			},
128
+			watchFunc: func(resourceVersion string) (watch.Interface, error) {
129
+				return c.clusterPolicyRegistry.WatchClusterPolicies(ctx, labels.Everything(), fields.Everything(), resourceVersion)
130
+			},
131
+		},
132
+		&authorizationapi.ClusterPolicy{},
133
+		c.clusterPolicyIndexer,
134
+		2*time.Minute,
135
+	)
136
+
137
+	return policyBindingReflector, policyReflector, clusterPolicyBindingReflector, clusterPolicyReflector
110 138
 }
111 139
 
112 140
 // GetPolicy retrieves a specific policy.  It conforms to rulevalidation.PolicyGetter.
113 141
 func (c *PolicyCache) GetPolicy(ctx kapi.Context, name string) (*authorizationapi.Policy, error) {
114
-	namespace, exists := kapi.NamespaceFrom(ctx)
115
-	if !exists {
116
-		return nil, errors.New("no namespace found")
117
-	}
118
-
119
-	keyObj := &authorizationapi.Policy{ObjectMeta: kapi.ObjectMeta{Namespace: namespace, Name: name}}
120
-	key, _ := c.keyFunc(keyObj)
121
-
122
-	policy, exists, err := c.policyIndexer.GetByKey(key)
123
-	if err != nil {
124
-		return nil, err
125
-	}
126
-	if !exists {
127
-		return nil, fmt.Errorf("%v not found", key)
142
+	namespace, _ := kapi.NamespaceFrom(ctx)
143
+
144
+	switch {
145
+	case len(namespace) == 0:
146
+		keyObj := &authorizationapi.ClusterPolicy{ObjectMeta: kapi.ObjectMeta{Name: name}}
147
+		key, _ := c.keyFunc(keyObj)
148
+
149
+		policy, exists, err := c.clusterPolicyIndexer.GetByKey(key)
150
+		if err != nil {
151
+			return nil, err
152
+		}
153
+		if !exists {
154
+			return nil, fmt.Errorf("%v not found", key)
155
+		}
156
+
157
+		return authorizationapi.ToPolicy(policy.(*authorizationapi.ClusterPolicy)), nil
158
+
159
+	default:
160
+		keyObj := &authorizationapi.Policy{ObjectMeta: kapi.ObjectMeta{Namespace: namespace, Name: name}}
161
+		key, _ := c.keyFunc(keyObj)
162
+
163
+		policy, exists, err := c.policyIndexer.GetByKey(key)
164
+		if err != nil {
165
+			return nil, err
166
+		}
167
+		if !exists {
168
+			return nil, fmt.Errorf("%v not found", key)
169
+		}
170
+
171
+		return policy.(*authorizationapi.Policy), nil
128 172
 	}
129
-
130
-	return policy.(*authorizationapi.Policy), nil
131 173
 }
132 174
 
133 175
 // ListPolicyBindings obtains list of policyBindings that match a selector.  It conforms to rulevalidation.BindingLister
134 176
 func (c *PolicyCache) ListPolicyBindings(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.PolicyBindingList, error) {
135
-	namespace, exists := kapi.NamespaceFrom(ctx)
136
-	if !exists {
137
-		return nil, errors.New("no namespace found")
138
-	}
139
-
140
-	bindings, err := c.policyBindingIndexer.Index("namespace", &authorizationapi.PolicyBinding{ObjectMeta: kapi.ObjectMeta{Namespace: namespace}})
141
-	if err != nil {
142
-		return nil, err
177
+	namespace, _ := kapi.NamespaceFrom(ctx)
178
+
179
+	switch {
180
+	case len(namespace) == 0:
181
+		bindings, err := c.clusterPolicyBindingIndexer.Index("namespace", &authorizationapi.ClusterPolicyBinding{})
182
+		if err != nil {
183
+			return nil, err
184
+		}
185
+
186
+		ret := &authorizationapi.PolicyBindingList{
187
+			Items: make([]authorizationapi.PolicyBinding, 0, len(bindings)),
188
+		}
189
+		for i := range bindings {
190
+			ret.Items = append(ret.Items, *authorizationapi.ToPolicyBinding(bindings[i].(*authorizationapi.ClusterPolicyBinding)))
191
+		}
192
+
193
+		return ret, nil
194
+
195
+	default:
196
+		bindings, err := c.policyBindingIndexer.Index("namespace", &authorizationapi.PolicyBinding{ObjectMeta: kapi.ObjectMeta{Namespace: namespace}})
197
+		if err != nil {
198
+			return nil, err
199
+		}
200
+
201
+		ret := &authorizationapi.PolicyBindingList{
202
+			Items: make([]authorizationapi.PolicyBinding, 0, len(bindings)),
203
+		}
204
+		for i := range bindings {
205
+			ret.Items = append(ret.Items, *bindings[i].(*authorizationapi.PolicyBinding))
206
+		}
207
+
208
+		return ret, nil
143 209
 	}
144
-
145
-	ret := &authorizationapi.PolicyBindingList{
146
-		Items: make([]authorizationapi.PolicyBinding, 0, len(bindings)),
147
-	}
148
-	for i := range bindings {
149
-		ret.Items = append(ret.Items, *bindings[i].(*authorizationapi.PolicyBinding))
150
-	}
151
-
152
-	return ret, nil
153 210
 }
... ...
@@ -19,10 +19,10 @@ func TestPolicyGet(t *testing.T) {
19 19
 	defer close(policyStop)
20 20
 	defer close(bindingStop)
21 21
 
22
-	policyRegistry := testregistry.NewPolicyRegistry(testPolicies(), nil)
23
-	bindingRegistry := testregistry.NewPolicyBindingRegistry(testBindings(), nil)
22
+	policyRegistry := testregistry.NewPolicyRegistry(testLocalPolicies(), nil)
23
+	bindingRegistry := testregistry.NewPolicyBindingRegistry(testLocalBindings(), nil)
24 24
 
25
-	policyCache := NewPolicyCache(bindingRegistry, policyRegistry)
25
+	policyCache := NewPolicyCache(bindingRegistry, policyRegistry, &testregistry.ClusterPolicyBindingRegistry{}, &testregistry.ClusterPolicyRegistry{})
26 26
 	policyCache.RunUntil(bindingStop, policyStop)
27 27
 
28 28
 	testStop := make(chan struct{})
... ...
@@ -39,7 +39,7 @@ func TestPolicyGet(t *testing.T) {
39 39
 	}, 1*time.Millisecond, testStop)
40 40
 }
41 41
 
42
-func testPolicies() []authorizationapi.Policy {
42
+func testLocalPolicies() []authorizationapi.Policy {
43 43
 	return []authorizationapi.Policy{
44 44
 		{
45 45
 			ObjectMeta: kapi.ObjectMeta{
... ...
@@ -49,7 +49,8 @@ func testPolicies() []authorizationapi.Policy {
49 49
 			Roles: map[string]authorizationapi.Role{},
50 50
 		}}
51 51
 }
52
-func testBindings() []authorizationapi.PolicyBinding {
52
+
53
+func testLocalBindings() []authorizationapi.PolicyBinding {
53 54
 	return []authorizationapi.PolicyBinding{
54 55
 		{
55 56
 			ObjectMeta: kapi.ObjectMeta{
56 57
new file mode 100644
... ...
@@ -0,0 +1,48 @@
0
+package etcd
1
+
2
+import (
3
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
4
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
5
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
7
+	etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
8
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
9
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
10
+
11
+	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
12
+	"github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
13
+)
14
+
15
+const ClusterPolicyPath = "/registry/authorization/clusterpolicy"
16
+
17
+type REST struct {
18
+	*etcdgeneric.Etcd
19
+}
20
+
21
+// NewStorage returns a RESTStorage object that will work against nodes.
22
+func NewStorage(h tools.EtcdHelper) *REST {
23
+	store := &etcdgeneric.Etcd{
24
+		NewFunc:      func() runtime.Object { return &authorizationapi.ClusterPolicy{} },
25
+		NewListFunc:  func() runtime.Object { return &authorizationapi.ClusterPolicyList{} },
26
+		EndpointName: "clusterpolicy",
27
+		KeyRootFunc: func(ctx kapi.Context) string {
28
+			return ClusterPolicyPath
29
+		},
30
+		KeyFunc: func(ctx kapi.Context, id string) (string, error) {
31
+			return etcdgeneric.NoNamespaceKeyFunc(ctx, ClusterPolicyPath, id)
32
+		},
33
+		ObjectNameFunc: func(obj runtime.Object) (string, error) {
34
+			return obj.(*authorizationapi.ClusterPolicy).Name, nil
35
+		},
36
+		PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher {
37
+			return clusterpolicy.Matcher(label, field)
38
+		},
39
+
40
+		CreateStrategy: clusterpolicy.Strategy,
41
+		UpdateStrategy: clusterpolicy.Strategy,
42
+
43
+		Helper: h,
44
+	}
45
+
46
+	return &REST{store}
47
+}
0 48
deleted file mode 100644
... ...
@@ -1,77 +0,0 @@
1
-package proxy
2
-
3
-import (
4
-	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
5
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
6
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
7
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
8
-
9
-	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
10
-	policyregistry "github.com/openshift/origin/pkg/authorization/registry/policy"
11
-)
12
-
13
-type ClusterPolicyStorage struct {
14
-	masterNamespace string
15
-	typeConverter   authorizationapi.TypeConverter
16
-	policyStorage   policyregistry.Storage
17
-}
18
-
19
-func NewClusterPolicyStorage(masterNamespace string, policyStorage policyregistry.Storage) *ClusterPolicyStorage {
20
-	return &ClusterPolicyStorage{masterNamespace, authorizationapi.TypeConverter{masterNamespace}, policyStorage}
21
-}
22
-
23
-func (s *ClusterPolicyStorage) New() runtime.Object {
24
-	return &authorizationapi.ClusterPolicy{}
25
-}
26
-func (s *ClusterPolicyStorage) NewList() runtime.Object {
27
-	return &authorizationapi.ClusterPolicyList{}
28
-}
29
-
30
-func (s *ClusterPolicyStorage) List(ctx kapi.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
31
-	ret, err := s.policyStorage.List(kapi.WithNamespace(ctx, s.masterNamespace), label, field)
32
-	if ret == nil {
33
-		return nil, err
34
-	}
35
-	return s.typeConverter.ToClusterPolicyList(ret.(*authorizationapi.PolicyList)), err
36
-}
37
-
38
-func (s *ClusterPolicyStorage) Get(ctx kapi.Context, name string) (runtime.Object, error) {
39
-	ret, err := s.policyStorage.Get(kapi.WithNamespace(ctx, s.masterNamespace), name)
40
-	if ret == nil {
41
-		return nil, err
42
-	}
43
-
44
-	return s.typeConverter.ToClusterPolicy(ret.(*authorizationapi.Policy)), err
45
-}
46
-func (s *ClusterPolicyStorage) Delete(ctx kapi.Context, name string, options *kapi.DeleteOptions) (runtime.Object, error) {
47
-	ret, err := s.policyStorage.Delete(kapi.WithNamespace(ctx, s.masterNamespace), name, options)
48
-	if ret == nil {
49
-		return nil, err
50
-	}
51
-
52
-	return s.typeConverter.ToClusterPolicy(ret.(*authorizationapi.Policy)), err
53
-}
54
-
55
-func (s *ClusterPolicyStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) {
56
-	clusterObj := obj.(*authorizationapi.ClusterPolicy)
57
-	convertedObj := s.typeConverter.ToPolicy(clusterObj)
58
-
59
-	ret, err := s.policyStorage.Create(kapi.WithNamespace(ctx, s.masterNamespace), convertedObj)
60
-	if ret == nil {
61
-		return nil, err
62
-	}
63
-
64
-	return s.typeConverter.ToClusterPolicy(ret.(*authorizationapi.Policy)), err
65
-}
66
-
67
-func (s *ClusterPolicyStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) {
68
-	clusterObj := obj.(*authorizationapi.ClusterPolicy)
69
-	convertedObj := s.typeConverter.ToPolicy(clusterObj)
70
-
71
-	ret, created, err := s.policyStorage.Update(kapi.WithNamespace(ctx, s.masterNamespace), convertedObj)
72
-	if ret == nil {
73
-		return nil, created, err
74
-	}
75
-
76
-	return s.typeConverter.ToClusterPolicy(ret.(*authorizationapi.Policy)), created, err
77
-}
78 1
new file mode 100644
... ...
@@ -0,0 +1,114 @@
0
+package clusterpolicy
1
+
2
+import (
3
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
4
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
5
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
7
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
8
+
9
+	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
10
+	"github.com/openshift/origin/pkg/authorization/registry/policy"
11
+)
12
+
13
+// Registry is an interface for things that know how to store ClusterPolicies.
14
+type Registry interface {
15
+	// ListClusterPolicies obtains list of policies that match a selector.
16
+	ListClusterPolicies(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.ClusterPolicyList, error)
17
+	// GetClusterPolicy retrieves a specific policy.
18
+	GetClusterPolicy(ctx kapi.Context, id string) (*authorizationapi.ClusterPolicy, error)
19
+	// CreateClusterPolicy creates a new policy.
20
+	CreateClusterPolicy(ctx kapi.Context, policy *authorizationapi.ClusterPolicy) error
21
+	// UpdateClusterPolicy updates a policy.
22
+	UpdateClusterPolicy(ctx kapi.Context, policy *authorizationapi.ClusterPolicy) error
23
+	// DeleteClusterPolicy deletes a policy.
24
+	DeleteClusterPolicy(ctx kapi.Context, id string) error
25
+}
26
+
27
+type WatchingRegistry interface {
28
+	Registry
29
+	// WatchClusterPolicies watches policies.
30
+	WatchClusterPolicies(ctx kapi.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
31
+}
32
+
33
+// Storage is an interface for a standard REST Storage backend
34
+type Storage interface {
35
+	rest.StandardStorage
36
+}
37
+
38
+// storage puts strong typing around storage calls
39
+type storage struct {
40
+	Storage
41
+}
42
+
43
+// NewRegistry returns a new Registry interface for the given Storage. Any mismatched
44
+// types will panic.
45
+func NewRegistry(s Storage) WatchingRegistry {
46
+	return &storage{s}
47
+}
48
+
49
+func (s *storage) ListClusterPolicies(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.ClusterPolicyList, error) {
50
+	obj, err := s.List(ctx, label, field)
51
+	if err != nil {
52
+		return nil, err
53
+	}
54
+
55
+	return obj.(*authorizationapi.ClusterPolicyList), nil
56
+}
57
+
58
+func (s *storage) CreateClusterPolicy(ctx kapi.Context, node *authorizationapi.ClusterPolicy) error {
59
+	_, err := s.Create(ctx, node)
60
+	return err
61
+}
62
+
63
+func (s *storage) UpdateClusterPolicy(ctx kapi.Context, node *authorizationapi.ClusterPolicy) error {
64
+	_, _, err := s.Update(ctx, node)
65
+	return err
66
+}
67
+
68
+func (s *storage) WatchClusterPolicies(ctx kapi.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
69
+	return s.Watch(ctx, label, field, resourceVersion)
70
+}
71
+
72
+func (s *storage) GetClusterPolicy(ctx kapi.Context, name string) (*authorizationapi.ClusterPolicy, error) {
73
+	obj, err := s.Get(ctx, name)
74
+	if err != nil {
75
+		return nil, err
76
+	}
77
+	return obj.(*authorizationapi.ClusterPolicy), nil
78
+}
79
+
80
+func (s *storage) DeleteClusterPolicy(ctx kapi.Context, name string) error {
81
+	_, err := s.Delete(ctx, name, nil)
82
+	return err
83
+}
84
+
85
+type simulatedStorage struct {
86
+	clusterRegistry Registry
87
+}
88
+
89
+func NewSimulatedRegistry(clusterRegistry Registry) policy.Registry {
90
+	return &simulatedStorage{clusterRegistry}
91
+}
92
+
93
+func (s *simulatedStorage) ListPolicies(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.PolicyList, error) {
94
+	ret, err := s.clusterRegistry.ListClusterPolicies(ctx, label, field)
95
+	return authorizationapi.ToPolicyList(ret), err
96
+}
97
+
98
+func (s *simulatedStorage) CreatePolicy(ctx kapi.Context, policy *authorizationapi.Policy) error {
99
+	return s.clusterRegistry.CreateClusterPolicy(ctx, authorizationapi.ToClusterPolicy(policy))
100
+}
101
+
102
+func (s *simulatedStorage) UpdatePolicy(ctx kapi.Context, policy *authorizationapi.Policy) error {
103
+	return s.clusterRegistry.UpdateClusterPolicy(ctx, authorizationapi.ToClusterPolicy(policy))
104
+}
105
+
106
+func (s *simulatedStorage) GetPolicy(ctx kapi.Context, name string) (*authorizationapi.Policy, error) {
107
+	ret, err := s.clusterRegistry.GetClusterPolicy(ctx, name)
108
+	return authorizationapi.ToPolicy(ret), err
109
+}
110
+
111
+func (s *simulatedStorage) DeletePolicy(ctx kapi.Context, name string) error {
112
+	return s.clusterRegistry.DeleteClusterPolicy(ctx, name)
113
+}
0 114
new file mode 100644
... ...
@@ -0,0 +1,80 @@
0
+package clusterpolicy
1
+
2
+import (
3
+	"fmt"
4
+
5
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
7
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
8
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
9
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
10
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
11
+
12
+	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
13
+	"github.com/openshift/origin/pkg/authorization/api/validation"
14
+)
15
+
16
+// strategy implements behavior for nodes
17
+type strategy struct {
18
+	runtime.ObjectTyper
19
+}
20
+
21
+// Strategy is the default logic that applies when creating and updating ClusterPolicy objects.
22
+var Strategy = strategy{kapi.Scheme}
23
+
24
+func (strategy) NamespaceScoped() bool {
25
+	return false
26
+}
27
+
28
+// AllowCreateOnUpdate is false for policies.
29
+func (strategy) AllowCreateOnUpdate() bool {
30
+	return false
31
+}
32
+
33
+func (strategy) GenerateName(base string) string {
34
+	return base
35
+}
36
+
37
+// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
38
+func (strategy) PrepareForCreate(obj runtime.Object) {
39
+	policy := obj.(*authorizationapi.ClusterPolicy)
40
+
41
+	policy.Name = authorizationapi.PolicyName
42
+}
43
+
44
+// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
45
+func (strategy) PrepareForUpdate(obj, old runtime.Object) {
46
+	_ = obj.(*authorizationapi.ClusterPolicy)
47
+}
48
+
49
+// Validate validates a new policy.
50
+func (strategy) Validate(ctx kapi.Context, obj runtime.Object) fielderrors.ValidationErrorList {
51
+	return validation.ValidateClusterPolicy(obj.(*authorizationapi.ClusterPolicy))
52
+}
53
+
54
+// ValidateUpdate is the default update validation for an end user.
55
+func (strategy) ValidateUpdate(ctx kapi.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
56
+	return validation.ValidateClusterPolicyUpdate(obj.(*authorizationapi.ClusterPolicy), old.(*authorizationapi.ClusterPolicy))
57
+}
58
+
59
+// Matcher returns a generic matcher for a given label and field selector.
60
+func Matcher(label labels.Selector, field fields.Selector) generic.Matcher {
61
+	return &generic.SelectionPredicate{
62
+		Label: label,
63
+		Field: field,
64
+		GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
65
+			policy, ok := obj.(*authorizationapi.ClusterPolicy)
66
+			if !ok {
67
+				return nil, nil, fmt.Errorf("not a policy")
68
+			}
69
+			return labels.Set(policy.ObjectMeta.Labels), SelectableFields(policy), nil
70
+		},
71
+	}
72
+}
73
+
74
+// SelectableFields returns a label set that represents the object
75
+func SelectableFields(policy *authorizationapi.ClusterPolicy) fields.Set {
76
+	return fields.Set{
77
+		"name": policy.Name,
78
+	}
79
+}
0 80
new file mode 100644
... ...
@@ -0,0 +1,48 @@
0
+package etcd
1
+
2
+import (
3
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
4
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
5
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
7
+	etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
8
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
9
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
10
+
11
+	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
12
+	"github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding"
13
+)
14
+
15
+const ClusterPolicyBindingPath = "/registry/authorization/clusterpolicybinding"
16
+
17
+type REST struct {
18
+	*etcdgeneric.Etcd
19
+}
20
+
21
+// NewStorage returns a RESTStorage object that will work against nodes.
22
+func NewStorage(h tools.EtcdHelper) *REST {
23
+	store := &etcdgeneric.Etcd{
24
+		NewFunc:      func() runtime.Object { return &authorizationapi.ClusterPolicyBinding{} },
25
+		NewListFunc:  func() runtime.Object { return &authorizationapi.ClusterPolicyBindingList{} },
26
+		EndpointName: "clusterpolicybinding",
27
+		KeyRootFunc: func(ctx kapi.Context) string {
28
+			return ClusterPolicyBindingPath
29
+		},
30
+		KeyFunc: func(ctx kapi.Context, id string) (string, error) {
31
+			return etcdgeneric.NoNamespaceKeyFunc(ctx, ClusterPolicyBindingPath, id)
32
+		},
33
+		ObjectNameFunc: func(obj runtime.Object) (string, error) {
34
+			return obj.(*authorizationapi.ClusterPolicyBinding).Name, nil
35
+		},
36
+		PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher {
37
+			return clusterpolicybinding.Matcher(label, field)
38
+		},
39
+
40
+		CreateStrategy: clusterpolicybinding.Strategy,
41
+		UpdateStrategy: clusterpolicybinding.Strategy,
42
+
43
+		Helper: h,
44
+	}
45
+
46
+	return &REST{store}
47
+}
0 48
deleted file mode 100644
... ...
@@ -1,77 +0,0 @@
1
-package proxy
2
-
3
-import (
4
-	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
5
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
6
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
7
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
8
-
9
-	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
10
-	policybindingregistry "github.com/openshift/origin/pkg/authorization/registry/policybinding"
11
-)
12
-
13
-type ClusterPolicyBindingStorage struct {
14
-	masterNamespace      string
15
-	typeConverter        authorizationapi.TypeConverter
16
-	policyBindingStorage policybindingregistry.Storage
17
-}
18
-
19
-func NewClusterPolicyBindingStorage(masterNamespace string, policyBindingStorage policybindingregistry.Storage) *ClusterPolicyBindingStorage {
20
-	return &ClusterPolicyBindingStorage{masterNamespace, authorizationapi.TypeConverter{masterNamespace}, policyBindingStorage}
21
-}
22
-
23
-func (s *ClusterPolicyBindingStorage) New() runtime.Object {
24
-	return &authorizationapi.ClusterPolicyBinding{}
25
-}
26
-func (s *ClusterPolicyBindingStorage) NewList() runtime.Object {
27
-	return &authorizationapi.ClusterPolicyBindingList{}
28
-}
29
-
30
-func (s *ClusterPolicyBindingStorage) List(ctx kapi.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
31
-	ret, err := s.policyBindingStorage.List(kapi.WithNamespace(ctx, s.masterNamespace), label, field)
32
-	if ret == nil {
33
-		return nil, err
34
-	}
35
-	return s.typeConverter.ToClusterPolicyBindingList(ret.(*authorizationapi.PolicyBindingList)), err
36
-}
37
-
38
-func (s *ClusterPolicyBindingStorage) Get(ctx kapi.Context, name string) (runtime.Object, error) {
39
-	ret, err := s.policyBindingStorage.Get(kapi.WithNamespace(ctx, s.masterNamespace), name)
40
-	if ret == nil {
41
-		return nil, err
42
-	}
43
-
44
-	return s.typeConverter.ToClusterPolicyBinding(ret.(*authorizationapi.PolicyBinding)), err
45
-}
46
-func (s *ClusterPolicyBindingStorage) Delete(ctx kapi.Context, name string, options *kapi.DeleteOptions) (runtime.Object, error) {
47
-	ret, err := s.policyBindingStorage.Delete(kapi.WithNamespace(ctx, s.masterNamespace), name, options)
48
-	if ret == nil {
49
-		return nil, err
50
-	}
51
-
52
-	return s.typeConverter.ToClusterPolicyBinding(ret.(*authorizationapi.PolicyBinding)), err
53
-}
54
-
55
-func (s *ClusterPolicyBindingStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) {
56
-	clusterObj := obj.(*authorizationapi.ClusterPolicyBinding)
57
-	convertedObj := s.typeConverter.ToPolicyBinding(clusterObj)
58
-
59
-	ret, err := s.policyBindingStorage.Create(kapi.WithNamespace(ctx, s.masterNamespace), convertedObj)
60
-	if ret == nil {
61
-		return nil, err
62
-	}
63
-
64
-	return s.typeConverter.ToClusterPolicyBinding(ret.(*authorizationapi.PolicyBinding)), err
65
-}
66
-
67
-func (s *ClusterPolicyBindingStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) {
68
-	clusterObj := obj.(*authorizationapi.ClusterPolicyBinding)
69
-	convertedObj := s.typeConverter.ToPolicyBinding(clusterObj)
70
-
71
-	ret, created, err := s.policyBindingStorage.Update(kapi.WithNamespace(ctx, s.masterNamespace), convertedObj)
72
-	if ret == nil {
73
-		return nil, created, err
74
-	}
75
-
76
-	return s.typeConverter.ToClusterPolicyBinding(ret.(*authorizationapi.PolicyBinding)), created, err
77
-}
78 1
new file mode 100644
... ...
@@ -0,0 +1,114 @@
0
+package clusterpolicybinding
1
+
2
+import (
3
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
4
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
5
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
7
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
8
+
9
+	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
10
+	"github.com/openshift/origin/pkg/authorization/registry/policybinding"
11
+)
12
+
13
+// Registry is an interface for things that know how to store ClusterPolicyBindings.
14
+type Registry interface {
15
+	// ListClusterPolicyBindings obtains list of policyBindings that match a selector.
16
+	ListClusterPolicyBindings(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.ClusterPolicyBindingList, error)
17
+	// GetClusterPolicyBinding retrieves a specific policyBinding.
18
+	GetClusterPolicyBinding(ctx kapi.Context, name string) (*authorizationapi.ClusterPolicyBinding, error)
19
+	// CreateClusterPolicyBinding creates a new policyBinding.
20
+	CreateClusterPolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.ClusterPolicyBinding) error
21
+	// UpdateClusterPolicyBinding updates a policyBinding.
22
+	UpdateClusterPolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.ClusterPolicyBinding) error
23
+	// DeleteClusterPolicyBinding deletes a policyBinding.
24
+	DeleteClusterPolicyBinding(ctx kapi.Context, name string) error
25
+}
26
+
27
+type WatchingRegistry interface {
28
+	Registry
29
+	// WatchClusterPolicyBindings watches policyBindings.
30
+	WatchClusterPolicyBindings(ctx kapi.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
31
+}
32
+
33
+// Storage is an interface for a standard REST Storage backend
34
+type Storage interface {
35
+	rest.StandardStorage
36
+}
37
+
38
+// storage puts strong typing around storage calls
39
+type storage struct {
40
+	Storage
41
+}
42
+
43
+// NewRegistry returns a new Registry interface for the given Storage. Any mismatched
44
+// types will panic.
45
+func NewRegistry(s Storage) WatchingRegistry {
46
+	return &storage{s}
47
+}
48
+
49
+func (s *storage) ListClusterPolicyBindings(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.ClusterPolicyBindingList, error) {
50
+	obj, err := s.List(ctx, label, field)
51
+	if err != nil {
52
+		return nil, err
53
+	}
54
+
55
+	return obj.(*authorizationapi.ClusterPolicyBindingList), nil
56
+}
57
+
58
+func (s *storage) CreateClusterPolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.ClusterPolicyBinding) error {
59
+	_, err := s.Create(ctx, policyBinding)
60
+	return err
61
+}
62
+
63
+func (s *storage) UpdateClusterPolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.ClusterPolicyBinding) error {
64
+	_, _, err := s.Update(ctx, policyBinding)
65
+	return err
66
+}
67
+
68
+func (s *storage) WatchClusterPolicyBindings(ctx kapi.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
69
+	return s.Watch(ctx, label, field, resourceVersion)
70
+}
71
+
72
+func (s *storage) GetClusterPolicyBinding(ctx kapi.Context, name string) (*authorizationapi.ClusterPolicyBinding, error) {
73
+	obj, err := s.Get(ctx, name)
74
+	if err != nil {
75
+		return nil, err
76
+	}
77
+	return obj.(*authorizationapi.ClusterPolicyBinding), nil
78
+}
79
+
80
+func (s *storage) DeleteClusterPolicyBinding(ctx kapi.Context, name string) error {
81
+	_, err := s.Delete(ctx, name, nil)
82
+	return err
83
+}
84
+
85
+type simulatedStorage struct {
86
+	clusterRegistry Registry
87
+}
88
+
89
+func NewSimulatedRegistry(clusterRegistry Registry) policybinding.Registry {
90
+	return &simulatedStorage{clusterRegistry}
91
+}
92
+
93
+func (s *simulatedStorage) ListPolicyBindings(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.PolicyBindingList, error) {
94
+	ret, err := s.clusterRegistry.ListClusterPolicyBindings(ctx, label, field)
95
+	return authorizationapi.ToPolicyBindingList(ret), err
96
+}
97
+
98
+func (s *simulatedStorage) CreatePolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.PolicyBinding) error {
99
+	return s.clusterRegistry.CreateClusterPolicyBinding(ctx, authorizationapi.ToClusterPolicyBinding(policyBinding))
100
+}
101
+
102
+func (s *simulatedStorage) UpdatePolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.PolicyBinding) error {
103
+	return s.clusterRegistry.UpdateClusterPolicyBinding(ctx, authorizationapi.ToClusterPolicyBinding(policyBinding))
104
+}
105
+
106
+func (s *simulatedStorage) GetPolicyBinding(ctx kapi.Context, name string) (*authorizationapi.PolicyBinding, error) {
107
+	ret, err := s.clusterRegistry.GetClusterPolicyBinding(ctx, name)
108
+	return authorizationapi.ToPolicyBinding(ret), err
109
+}
110
+
111
+func (s *simulatedStorage) DeletePolicyBinding(ctx kapi.Context, name string) error {
112
+	return s.clusterRegistry.DeleteClusterPolicyBinding(ctx, name)
113
+}
0 114
new file mode 100644
... ...
@@ -0,0 +1,96 @@
0
+package clusterpolicybinding
1
+
2
+import (
3
+	"fmt"
4
+
5
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
7
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
8
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
9
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
10
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
11
+
12
+	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
13
+	"github.com/openshift/origin/pkg/authorization/api/validation"
14
+)
15
+
16
+// strategy implements behavior for nodes
17
+type strategy struct {
18
+	runtime.ObjectTyper
19
+}
20
+
21
+// Strategy is the default logic that applies when creating and updating ClusterPolicyBinding objects.
22
+var Strategy = strategy{kapi.Scheme}
23
+
24
+func (strategy) NamespaceScoped() bool {
25
+	return false
26
+}
27
+
28
+// AllowCreateOnUpdate is false for policybindings.
29
+func (strategy) AllowCreateOnUpdate() bool {
30
+	return false
31
+}
32
+
33
+func (strategy) GenerateName(base string) string {
34
+	return base
35
+}
36
+
37
+// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
38
+func (s strategy) PrepareForCreate(obj runtime.Object) {
39
+	binding := obj.(*authorizationapi.ClusterPolicyBinding)
40
+
41
+	s.scrubBindingRefs(binding)
42
+	// force a delimited name, just in case we someday allow a reference to a global object that won't have a namespace.  We'll end up with a name like ":default".
43
+	// ":" is not in the value space of namespaces, so no escaping is necessary
44
+	binding.Name = authorizationapi.GetPolicyBindingName(binding.PolicyRef.Namespace)
45
+}
46
+
47
+// scrubBindingRefs discards pieces of the object references that we don't respect to avoid confusion.
48
+func (s strategy) scrubBindingRefs(binding *authorizationapi.ClusterPolicyBinding) {
49
+	binding.PolicyRef = kapi.ObjectReference{Namespace: binding.PolicyRef.Namespace, Name: authorizationapi.PolicyName}
50
+	binding.PolicyRef.Namespace = ""
51
+
52
+	for roleBindingKey, roleBinding := range binding.RoleBindings {
53
+		roleBinding.RoleRef = kapi.ObjectReference{Namespace: binding.PolicyRef.Namespace, Name: roleBinding.RoleRef.Name}
54
+		binding.RoleBindings[roleBindingKey] = roleBinding
55
+	}
56
+}
57
+
58
+// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
59
+func (s strategy) PrepareForUpdate(obj, old runtime.Object) {
60
+	binding := obj.(*authorizationapi.ClusterPolicyBinding)
61
+
62
+	s.scrubBindingRefs(binding)
63
+}
64
+
65
+// Validate validates a new policyBinding.
66
+func (strategy) Validate(ctx kapi.Context, obj runtime.Object) fielderrors.ValidationErrorList {
67
+	return validation.ValidateClusterPolicyBinding(obj.(*authorizationapi.ClusterPolicyBinding))
68
+}
69
+
70
+// ValidateUpdate is the default update validation for an end user.
71
+func (strategy) ValidateUpdate(ctx kapi.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
72
+	return validation.ValidateClusterPolicyBindingUpdate(obj.(*authorizationapi.ClusterPolicyBinding), old.(*authorizationapi.ClusterPolicyBinding))
73
+}
74
+
75
+// Matcher returns a generic matcher for a given label and field selector.
76
+func Matcher(label labels.Selector, field fields.Selector) generic.Matcher {
77
+	return &generic.SelectionPredicate{
78
+		Label: label,
79
+		Field: field,
80
+		GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
81
+			policyBinding, ok := obj.(*authorizationapi.ClusterPolicyBinding)
82
+			if !ok {
83
+				return nil, nil, fmt.Errorf("not a policyBinding")
84
+			}
85
+			return labels.Set(policyBinding.ObjectMeta.Labels), SelectableFields(policyBinding), nil
86
+		},
87
+	}
88
+}
89
+
90
+// SelectableFields returns a label set that represents the object
91
+func SelectableFields(policyBinding *authorizationapi.ClusterPolicyBinding) fields.Set {
92
+	return fields.Set{
93
+		"name": policyBinding.Name,
94
+	}
95
+}
... ...
@@ -7,17 +7,17 @@ import (
7 7
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
8 8
 
9 9
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
10
+	clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
10 11
 	roleregistry "github.com/openshift/origin/pkg/authorization/registry/role"
12
+	rolestorage "github.com/openshift/origin/pkg/authorization/registry/role/policybased"
11 13
 )
12 14
 
13 15
 type ClusterRoleStorage struct {
14
-	masterNamespace string
15
-	typeConverter   authorizationapi.TypeConverter
16
-	roleStorage     roleregistry.Storage
16
+	roleStorage rolestorage.VirtualStorage
17 17
 }
18 18
 
19
-func NewClusterRoleStorage(masterNamespace string, roleStorage roleregistry.Storage) *ClusterRoleStorage {
20
-	return &ClusterRoleStorage{masterNamespace, authorizationapi.TypeConverter{masterNamespace}, roleStorage}
19
+func NewClusterRoleStorage(clusterPolicyRegistry clusterpolicyregistry.Registry) *ClusterRoleStorage {
20
+	return &ClusterRoleStorage{rolestorage.VirtualStorage{clusterpolicyregistry.NewSimulatedRegistry(clusterPolicyRegistry), roleregistry.ClusterStrategy, roleregistry.ClusterStrategy}}
21 21
 }
22 22
 
23 23
 func (s *ClusterRoleStorage) New() runtime.Object {
... ...
@@ -28,50 +28,50 @@ func (s *ClusterRoleStorage) NewList() runtime.Object {
28 28
 }
29 29
 
30 30
 func (s *ClusterRoleStorage) List(ctx kapi.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
31
-	ret, err := s.roleStorage.List(kapi.WithNamespace(ctx, s.masterNamespace), label, field)
31
+	ret, err := s.roleStorage.List(ctx, label, field)
32 32
 	if ret == nil {
33 33
 		return nil, err
34 34
 	}
35
-	return s.typeConverter.ToClusterRoleList(ret.(*authorizationapi.RoleList)), err
35
+	return authorizationapi.ToClusterRoleList(ret.(*authorizationapi.RoleList)), err
36 36
 }
37 37
 
38 38
 func (s *ClusterRoleStorage) Get(ctx kapi.Context, name string) (runtime.Object, error) {
39
-	ret, err := s.roleStorage.Get(kapi.WithNamespace(ctx, s.masterNamespace), name)
39
+	ret, err := s.roleStorage.Get(ctx, name)
40 40
 	if ret == nil {
41 41
 		return nil, err
42 42
 	}
43 43
 
44
-	return s.typeConverter.ToClusterRole(ret.(*authorizationapi.Role)), err
44
+	return authorizationapi.ToClusterRole(ret.(*authorizationapi.Role)), err
45 45
 }
46 46
 func (s *ClusterRoleStorage) Delete(ctx kapi.Context, name string, options *kapi.DeleteOptions) (runtime.Object, error) {
47
-	ret, err := s.roleStorage.Delete(kapi.WithNamespace(ctx, s.masterNamespace), name, options)
47
+	ret, err := s.roleStorage.Delete(ctx, name, options)
48 48
 	if ret == nil {
49 49
 		return nil, err
50 50
 	}
51 51
 
52
-	return s.typeConverter.ToClusterRole(ret.(*authorizationapi.Role)), err
52
+	return ret.(*kapi.Status), err
53 53
 }
54 54
 
55 55
 func (s *ClusterRoleStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) {
56 56
 	clusterObj := obj.(*authorizationapi.ClusterRole)
57
-	convertedObj := s.typeConverter.ToRole(clusterObj)
57
+	convertedObj := authorizationapi.ToRole(clusterObj)
58 58
 
59
-	ret, err := s.roleStorage.Create(kapi.WithNamespace(ctx, s.masterNamespace), convertedObj)
59
+	ret, err := s.roleStorage.Create(ctx, convertedObj)
60 60
 	if ret == nil {
61 61
 		return nil, err
62 62
 	}
63 63
 
64
-	return s.typeConverter.ToClusterRole(ret.(*authorizationapi.Role)), err
64
+	return authorizationapi.ToClusterRole(ret.(*authorizationapi.Role)), err
65 65
 }
66 66
 
67 67
 func (s *ClusterRoleStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) {
68 68
 	clusterObj := obj.(*authorizationapi.ClusterRole)
69
-	convertedObj := s.typeConverter.ToRole(clusterObj)
69
+	convertedObj := authorizationapi.ToRole(clusterObj)
70 70
 
71
-	ret, created, err := s.roleStorage.Update(kapi.WithNamespace(ctx, s.masterNamespace), convertedObj)
71
+	ret, created, err := s.roleStorage.Update(ctx, convertedObj)
72 72
 	if ret == nil {
73 73
 		return nil, created, err
74 74
 	}
75 75
 
76
-	return s.typeConverter.ToClusterRole(ret.(*authorizationapi.Role)), created, err
76
+	return authorizationapi.ToClusterRole(ret.(*authorizationapi.Role)), created, err
77 77
 }
78 78
new file mode 100644
... ...
@@ -0,0 +1,75 @@
0
+package role
1
+
2
+import (
3
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
4
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
5
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
7
+
8
+	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
9
+)
10
+
11
+// Registry is an interface for things that know how to store ClusterRoles.
12
+type Registry interface {
13
+	// ListClusterRoles obtains list of policyClusterRoles that match a selector.
14
+	ListClusterRoles(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.ClusterRoleList, error)
15
+	// GetClusterRole retrieves a specific policyClusterRole.
16
+	GetClusterRole(ctx kapi.Context, id string) (*authorizationapi.ClusterRole, error)
17
+	// CreateClusterRole creates a new policyClusterRole.
18
+	CreateClusterRole(ctx kapi.Context, policyClusterRole *authorizationapi.ClusterRole) (*authorizationapi.ClusterRole, error)
19
+	// UpdateClusterRole updates a policyClusterRole.
20
+	UpdateClusterRole(ctx kapi.Context, policyClusterRole *authorizationapi.ClusterRole) (*authorizationapi.ClusterRole, bool, error)
21
+	// DeleteClusterRole deletes a policyClusterRole.
22
+	DeleteClusterRole(ctx kapi.Context, id string) error
23
+}
24
+
25
+// Storage is an interface for a standard REST Storage backend
26
+type Storage interface {
27
+	rest.Getter
28
+	rest.Lister
29
+	rest.CreaterUpdater
30
+	rest.GracefulDeleter
31
+}
32
+
33
+// storage puts strong typing around storage calls
34
+type storage struct {
35
+	Storage
36
+}
37
+
38
+// NewRegistry returns a new Registry interface for the given Storage. Any mismatched
39
+// types will panic.
40
+func NewRegistry(s Storage) Registry {
41
+	return &storage{s}
42
+}
43
+
44
+func (s *storage) ListClusterRoles(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.ClusterRoleList, error) {
45
+	obj, err := s.List(ctx, label, field)
46
+	if err != nil {
47
+		return nil, err
48
+	}
49
+
50
+	return obj.(*authorizationapi.ClusterRoleList), nil
51
+}
52
+
53
+func (s *storage) CreateClusterRole(ctx kapi.Context, node *authorizationapi.ClusterRole) (*authorizationapi.ClusterRole, error) {
54
+	obj, err := s.Create(ctx, node)
55
+	return obj.(*authorizationapi.ClusterRole), err
56
+}
57
+
58
+func (s *storage) UpdateClusterRole(ctx kapi.Context, node *authorizationapi.ClusterRole) (*authorizationapi.ClusterRole, bool, error) {
59
+	obj, created, err := s.Update(ctx, node)
60
+	return obj.(*authorizationapi.ClusterRole), created, err
61
+}
62
+
63
+func (s *storage) GetClusterRole(ctx kapi.Context, name string) (*authorizationapi.ClusterRole, error) {
64
+	obj, err := s.Get(ctx, name)
65
+	if err != nil {
66
+		return nil, err
67
+	}
68
+	return obj.(*authorizationapi.ClusterRole), nil
69
+}
70
+
71
+func (s *storage) DeleteClusterRole(ctx kapi.Context, name string) error {
72
+	_, err := s.Delete(ctx, name, nil)
73
+	return err
74
+}
... ...
@@ -7,17 +7,31 @@ import (
7 7
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
8 8
 
9 9
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
10
+	clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
11
+	clusterpolicybindingregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding"
10 12
 	rolebindingregistry "github.com/openshift/origin/pkg/authorization/registry/rolebinding"
13
+	rolebindingstorage "github.com/openshift/origin/pkg/authorization/registry/rolebinding/policybased"
11 14
 )
12 15
 
13 16
 type ClusterRoleBindingStorage struct {
14
-	masterNamespace    string
15
-	typeConverter      authorizationapi.TypeConverter
16
-	roleBindingStorage rolebindingregistry.Storage
17
+	roleBindingStorage rolebindingstorage.VirtualStorage
17 18
 }
18 19
 
19
-func NewClusterRoleBindingStorage(masterNamespace string, roleBindingStorage rolebindingregistry.Storage) *ClusterRoleBindingStorage {
20
-	return &ClusterRoleBindingStorage{masterNamespace, authorizationapi.TypeConverter{masterNamespace}, roleBindingStorage}
20
+func NewClusterRoleBindingStorage(clusterPolicyRegistry clusterpolicyregistry.Registry, clusterBindingRegistry clusterpolicybindingregistry.Registry) *ClusterRoleBindingStorage {
21
+	simulatedPolicyRegistry := clusterpolicyregistry.NewSimulatedRegistry(clusterPolicyRegistry)
22
+	simulatedPolicyBindingRegistry := clusterpolicybindingregistry.NewSimulatedRegistry(clusterBindingRegistry)
23
+
24
+	return &ClusterRoleBindingStorage{
25
+		rolebindingstorage.VirtualStorage{
26
+			PolicyRegistry:               simulatedPolicyRegistry,
27
+			BindingRegistry:              simulatedPolicyBindingRegistry,
28
+			ClusterPolicyRegistry:        clusterPolicyRegistry,
29
+			ClusterPolicyBindingRegistry: clusterBindingRegistry,
30
+
31
+			CreateStrategy: rolebindingregistry.ClusterStrategy,
32
+			UpdateStrategy: rolebindingregistry.ClusterStrategy,
33
+		},
34
+	}
21 35
 }
22 36
 
23 37
 func (s *ClusterRoleBindingStorage) New() runtime.Object {
... ...
@@ -28,50 +42,62 @@ func (s *ClusterRoleBindingStorage) NewList() runtime.Object {
28 28
 }
29 29
 
30 30
 func (s *ClusterRoleBindingStorage) List(ctx kapi.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
31
-	ret, err := s.roleBindingStorage.List(kapi.WithNamespace(ctx, s.masterNamespace), label, field)
31
+	ret, err := s.roleBindingStorage.List(ctx, label, field)
32 32
 	if ret == nil {
33 33
 		return nil, err
34 34
 	}
35
-	return s.typeConverter.ToClusterRoleBindingList(ret.(*authorizationapi.RoleBindingList)), err
35
+	return authorizationapi.ToClusterRoleBindingList(ret.(*authorizationapi.RoleBindingList)), err
36 36
 }
37 37
 
38 38
 func (s *ClusterRoleBindingStorage) Get(ctx kapi.Context, name string) (runtime.Object, error) {
39
-	ret, err := s.roleBindingStorage.Get(kapi.WithNamespace(ctx, s.masterNamespace), name)
39
+	ret, err := s.roleBindingStorage.Get(ctx, name)
40 40
 	if ret == nil {
41 41
 		return nil, err
42 42
 	}
43 43
 
44
-	return s.typeConverter.ToClusterRoleBinding(ret.(*authorizationapi.RoleBinding)), err
44
+	return authorizationapi.ToClusterRoleBinding(ret.(*authorizationapi.RoleBinding)), err
45 45
 }
46 46
 func (s *ClusterRoleBindingStorage) Delete(ctx kapi.Context, name string, options *kapi.DeleteOptions) (runtime.Object, error) {
47
-	ret, err := s.roleBindingStorage.Delete(kapi.WithNamespace(ctx, s.masterNamespace), name, options)
47
+	ret, err := s.roleBindingStorage.Delete(ctx, name, options)
48 48
 	if ret == nil {
49 49
 		return nil, err
50 50
 	}
51 51
 
52
-	return s.typeConverter.ToClusterRoleBinding(ret.(*authorizationapi.RoleBinding)), err
52
+	return ret.(*kapi.Status), err
53 53
 }
54 54
 
55 55
 func (s *ClusterRoleBindingStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) {
56 56
 	clusterObj := obj.(*authorizationapi.ClusterRoleBinding)
57
-	convertedObj := s.typeConverter.ToRoleBinding(clusterObj)
57
+	convertedObj := authorizationapi.ToRoleBinding(clusterObj)
58 58
 
59
-	ret, err := s.roleBindingStorage.Create(kapi.WithNamespace(ctx, s.masterNamespace), convertedObj)
59
+	ret, err := s.roleBindingStorage.Create(ctx, convertedObj)
60 60
 	if ret == nil {
61 61
 		return nil, err
62 62
 	}
63 63
 
64
-	return s.typeConverter.ToClusterRoleBinding(ret.(*authorizationapi.RoleBinding)), err
64
+	return authorizationapi.ToClusterRoleBinding(ret.(*authorizationapi.RoleBinding)), err
65 65
 }
66 66
 
67 67
 func (s *ClusterRoleBindingStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.Object, bool, error) {
68 68
 	clusterObj := obj.(*authorizationapi.ClusterRoleBinding)
69
-	convertedObj := s.typeConverter.ToRoleBinding(clusterObj)
69
+	convertedObj := authorizationapi.ToRoleBinding(clusterObj)
70 70
 
71
-	ret, created, err := s.roleBindingStorage.Update(kapi.WithNamespace(ctx, s.masterNamespace), convertedObj)
71
+	ret, created, err := s.roleBindingStorage.Update(ctx, convertedObj)
72 72
 	if ret == nil {
73 73
 		return nil, created, err
74 74
 	}
75 75
 
76
-	return s.typeConverter.ToClusterRoleBinding(ret.(*authorizationapi.RoleBinding)), created, err
76
+	return authorizationapi.ToClusterRoleBinding(ret.(*authorizationapi.RoleBinding)), created, err
77
+}
78
+
79
+func (m *ClusterRoleBindingStorage) CreateClusterRoleBindingWithEscalation(ctx kapi.Context, obj *authorizationapi.ClusterRoleBinding) (*authorizationapi.ClusterRoleBinding, error) {
80
+	in := authorizationapi.ToRoleBinding(obj)
81
+	ret, err := m.roleBindingStorage.CreateRoleBindingWithEscalation(ctx, in)
82
+	return authorizationapi.ToClusterRoleBinding(ret), err
83
+}
84
+
85
+func (m *ClusterRoleBindingStorage) UpdateClusterRoleBindingWithEscalation(ctx kapi.Context, obj *authorizationapi.ClusterRoleBinding) (*authorizationapi.ClusterRoleBinding, bool, error) {
86
+	in := authorizationapi.ToRoleBinding(obj)
87
+	ret, created, err := m.roleBindingStorage.UpdateRoleBindingWithEscalation(ctx, in)
88
+	return authorizationapi.ToClusterRoleBinding(ret), created, err
77 89
 }
78 90
new file mode 100644
... ...
@@ -0,0 +1,80 @@
0
+package rolebinding
1
+
2
+import (
3
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
4
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
5
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
7
+
8
+	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
9
+)
10
+
11
+// Registry is an interface for things that know how to store RoleBindings.
12
+type Registry interface {
13
+	// ListRoleBindings obtains list of policyRoleBindings that match a selector.
14
+	ListRoleBindings(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.RoleBindingList, error)
15
+	// GetRoleBinding retrieves a specific policyRoleBinding.
16
+	GetRoleBinding(ctx kapi.Context, id string) (*authorizationapi.RoleBinding, error)
17
+	// CreateRoleBinding creates a new policyRoleBinding.
18
+	CreateRoleBinding(ctx kapi.Context, policyRoleBinding *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, error)
19
+	// UpdateRoleBinding updates a policyRoleBinding.
20
+	UpdateRoleBinding(ctx kapi.Context, policyRoleBinding *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, bool, error)
21
+	// DeleteRoleBinding deletes a policyRoleBinding.
22
+	DeleteRoleBinding(ctx kapi.Context, id string) error
23
+}
24
+
25
+// Storage is an interface for a standard REST Storage backend
26
+type Storage interface {
27
+	rest.Getter
28
+	rest.Lister
29
+	rest.CreaterUpdater
30
+	rest.GracefulDeleter
31
+
32
+	// CreateRoleBinding creates a new policyRoleBinding.  Skipping the escalation check should only be done during bootstrapping procedures where no users are currently bound.
33
+	CreateRoleBindingWithEscalation(ctx kapi.Context, policyRoleBinding *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, error)
34
+	// UpdateRoleBinding updates a policyRoleBinding.  Skipping the escalation check should only be done during bootstrapping procedures where no users are currently bound.
35
+	UpdateRoleBindingWithEscalation(ctx kapi.Context, policyRoleBinding *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, bool, error)
36
+}
37
+
38
+// storage puts strong typing around storage calls
39
+type storage struct {
40
+	Storage
41
+}
42
+
43
+// NewRegistry returns a new Registry interface for the given Storage. Any mismatched
44
+// types will panic.
45
+func NewRegistry(s Storage) Registry {
46
+	return &storage{s}
47
+}
48
+
49
+func (s *storage) ListRoleBindings(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.RoleBindingList, error) {
50
+	obj, err := s.List(ctx, label, field)
51
+	if err != nil {
52
+		return nil, err
53
+	}
54
+
55
+	return obj.(*authorizationapi.RoleBindingList), nil
56
+}
57
+
58
+func (s *storage) CreateRoleBinding(ctx kapi.Context, node *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, error) {
59
+	obj, err := s.Create(ctx, node)
60
+	return obj.(*authorizationapi.RoleBinding), err
61
+}
62
+
63
+func (s *storage) UpdateRoleBinding(ctx kapi.Context, node *authorizationapi.RoleBinding) (*authorizationapi.RoleBinding, bool, error) {
64
+	obj, created, err := s.Update(ctx, node)
65
+	return obj.(*authorizationapi.RoleBinding), created, err
66
+}
67
+
68
+func (s *storage) GetRoleBinding(ctx kapi.Context, name string) (*authorizationapi.RoleBinding, error) {
69
+	obj, err := s.Get(ctx, name)
70
+	if err != nil {
71
+		return nil, err
72
+	}
73
+	return obj.(*authorizationapi.RoleBinding), nil
74
+}
75
+
76
+func (s *storage) DeleteRoleBinding(ctx kapi.Context, name string) error {
77
+	_, err := s.Delete(ctx, name, nil)
78
+	return err
79
+}
... ...
@@ -22,7 +22,11 @@ type Registry interface {
22 22
 	UpdatePolicy(ctx kapi.Context, policy *authorizationapi.Policy) error
23 23
 	// DeletePolicy deletes a policy.
24 24
 	DeletePolicy(ctx kapi.Context, id string) error
25
-	// WatchPolicyBindings watches policies.
25
+}
26
+
27
+type WatchingRegistry interface {
28
+	Registry
29
+	// WatchPolicies watches policies.
26 30
 	WatchPolicies(ctx kapi.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
27 31
 }
28 32
 
... ...
@@ -38,7 +42,7 @@ type storage struct {
38 38
 
39 39
 // NewRegistry returns a new Registry interface for the given Storage. Any mismatched
40 40
 // types will panic.
41
-func NewRegistry(s Storage) Registry {
41
+func NewRegistry(s Storage) WatchingRegistry {
42 42
 	return &storage{s}
43 43
 }
44 44
 
... ...
@@ -50,12 +50,12 @@ func (strategy) PrepareForUpdate(obj, old runtime.Object) {
50 50
 
51 51
 // Validate validates a new policy.
52 52
 func (strategy) Validate(ctx kapi.Context, obj runtime.Object) fielderrors.ValidationErrorList {
53
-	return validation.ValidatePolicy(obj.(*authorizationapi.Policy))
53
+	return validation.ValidateLocalPolicy(obj.(*authorizationapi.Policy))
54 54
 }
55 55
 
56 56
 // ValidateUpdate is the default update validation for an end user.
57 57
 func (strategy) ValidateUpdate(ctx kapi.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
58
-	return validation.ValidatePolicyUpdate(obj.(*authorizationapi.Policy), old.(*authorizationapi.Policy))
58
+	return validation.ValidateLocalPolicyUpdate(obj.(*authorizationapi.Policy), old.(*authorizationapi.Policy))
59 59
 }
60 60
 
61 61
 // Matcher returns a generic matcher for a given label and field selector.
... ...
@@ -15,13 +15,17 @@ type Registry interface {
15 15
 	// ListPolicyBindings obtains list of policyBindings that match a selector.
16 16
 	ListPolicyBindings(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.PolicyBindingList, error)
17 17
 	// GetPolicyBinding retrieves a specific policyBinding.
18
-	GetPolicyBinding(ctx kapi.Context, id string) (*authorizationapi.PolicyBinding, error)
18
+	GetPolicyBinding(ctx kapi.Context, name string) (*authorizationapi.PolicyBinding, error)
19 19
 	// CreatePolicyBinding creates a new policyBinding.
20 20
 	CreatePolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.PolicyBinding) error
21 21
 	// UpdatePolicyBinding updates a policyBinding.
22 22
 	UpdatePolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.PolicyBinding) error
23 23
 	// DeletePolicyBinding deletes a policyBinding.
24
-	DeletePolicyBinding(ctx kapi.Context, id string) error
24
+	DeletePolicyBinding(ctx kapi.Context, name string) error
25
+}
26
+
27
+type WatchingRegistry interface {
28
+	Registry
25 29
 	// WatchPolicyBindings watches policyBindings.
26 30
 	WatchPolicyBindings(ctx kapi.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
27 31
 }
... ...
@@ -38,7 +42,7 @@ type storage struct {
38 38
 
39 39
 // NewRegistry returns a new Registry interface for the given Storage. Any mismatched
40 40
 // types will panic.
41
-func NewRegistry(s Storage) Registry {
41
+func NewRegistry(s Storage) WatchingRegistry {
42 42
 	return &storage{s}
43 43
 }
44 44
 
... ...
@@ -51,13 +55,13 @@ func (s *storage) ListPolicyBindings(ctx kapi.Context, label labels.Selector, fi
51 51
 	return obj.(*authorizationapi.PolicyBindingList), nil
52 52
 }
53 53
 
54
-func (s *storage) CreatePolicyBinding(ctx kapi.Context, node *authorizationapi.PolicyBinding) error {
55
-	_, err := s.Create(ctx, node)
54
+func (s *storage) CreatePolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.PolicyBinding) error {
55
+	_, err := s.Create(ctx, policyBinding)
56 56
 	return err
57 57
 }
58 58
 
59
-func (s *storage) UpdatePolicyBinding(ctx kapi.Context, node *authorizationapi.PolicyBinding) error {
60
-	_, _, err := s.Update(ctx, node)
59
+func (s *storage) UpdatePolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.PolicyBinding) error {
60
+	_, _, err := s.Update(ctx, policyBinding)
61 61
 	return err
62 62
 }
63 63
 
... ...
@@ -20,7 +20,6 @@ type strategy struct {
20 20
 	runtime.ObjectTyper
21 21
 }
22 22
 
23
-// Strategy is the default logic that applies when creating and updating PolicyBinding objects.
24 23
 var Strategy = strategy{kapi.Scheme}
25 24
 
26 25
 // NamespaceScoped is true for policybindings.
... ...
@@ -38,17 +37,17 @@ func (strategy) GenerateName(base string) string {
38 38
 }
39 39
 
40 40
 // PrepareForCreate clears fields that are not allowed to be set by end users on creation.
41
-func (strategy) PrepareForCreate(obj runtime.Object) {
41
+func (s strategy) PrepareForCreate(obj runtime.Object) {
42 42
 	binding := obj.(*authorizationapi.PolicyBinding)
43 43
 
44
-	scrubBindingRefs(binding)
44
+	s.scrubBindingRefs(binding)
45 45
 	// force a delimited name, just in case we someday allow a reference to a global object that won't have a namespace.  We'll end up with a name like ":default".
46 46
 	// ":" is not in the value space of namespaces, so no escaping is necessary
47 47
 	binding.Name = authorizationapi.GetPolicyBindingName(binding.PolicyRef.Namespace)
48 48
 }
49 49
 
50 50
 // scrubBindingRefs discards pieces of the object references that we don't respect to avoid confusion.
51
-func scrubBindingRefs(binding *authorizationapi.PolicyBinding) {
51
+func (s strategy) scrubBindingRefs(binding *authorizationapi.PolicyBinding) {
52 52
 	binding.PolicyRef = kapi.ObjectReference{Namespace: binding.PolicyRef.Namespace, Name: authorizationapi.PolicyName}
53 53
 
54 54
 	for roleBindingKey, roleBinding := range binding.RoleBindings {
... ...
@@ -58,20 +57,20 @@ func scrubBindingRefs(binding *authorizationapi.PolicyBinding) {
58 58
 }
59 59
 
60 60
 // PrepareForUpdate clears fields that are not allowed to be set by end users on update.
61
-func (strategy) PrepareForUpdate(obj, old runtime.Object) {
61
+func (s strategy) PrepareForUpdate(obj, old runtime.Object) {
62 62
 	binding := obj.(*authorizationapi.PolicyBinding)
63 63
 
64
-	scrubBindingRefs(binding)
64
+	s.scrubBindingRefs(binding)
65 65
 }
66 66
 
67 67
 // Validate validates a new policyBinding.
68 68
 func (strategy) Validate(ctx kapi.Context, obj runtime.Object) fielderrors.ValidationErrorList {
69
-	return validation.ValidatePolicyBinding(obj.(*authorizationapi.PolicyBinding))
69
+	return validation.ValidateLocalPolicyBinding(obj.(*authorizationapi.PolicyBinding))
70 70
 }
71 71
 
72 72
 // ValidateUpdate is the default update validation for an end user.
73 73
 func (strategy) ValidateUpdate(ctx kapi.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
74
-	return validation.ValidatePolicyBindingUpdate(obj.(*authorizationapi.PolicyBinding), old.(*authorizationapi.PolicyBinding))
74
+	return validation.ValidateLocalPolicyBindingUpdate(obj.(*authorizationapi.PolicyBinding), old.(*authorizationapi.PolicyBinding))
75 75
 }
76 76
 
77 77
 // Matcher returns a generic matcher for a given label and field selector.
... ...
@@ -19,12 +19,15 @@ import (
19 19
 // TODO sort out resourceVersions.  Perhaps a hash of the object contents?
20 20
 
21 21
 type VirtualStorage struct {
22
-	policyStorage policyregistry.Registry
22
+	PolicyStorage policyregistry.Registry
23
+
24
+	CreateStrategy rest.RESTCreateStrategy
25
+	UpdateStrategy rest.RESTUpdateStrategy
23 26
 }
24 27
 
25 28
 // NewVirtualStorage creates a new REST for policies.
26 29
 func NewVirtualStorage(policyStorage policyregistry.Registry) roleregistry.Storage {
27
-	return &VirtualStorage{policyStorage}
30
+	return &VirtualStorage{policyStorage, roleregistry.LocalStrategy, roleregistry.LocalStrategy}
28 31
 }
29 32
 
30 33
 func (m *VirtualStorage) New() runtime.Object {
... ...
@@ -36,7 +39,7 @@ func (m *VirtualStorage) NewList() runtime.Object {
36 36
 
37 37
 // TODO either add selector for fields ot eliminate the option
38 38
 func (m *VirtualStorage) List(ctx kapi.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
39
-	policyList, err := m.policyStorage.ListPolicies(ctx, labels.Everything(), fields.Everything())
39
+	policyList, err := m.PolicyStorage.ListPolicies(ctx, labels.Everything(), fields.Everything())
40 40
 	if err != nil {
41 41
 		return nil, err
42 42
 	}
... ...
@@ -55,7 +58,7 @@ func (m *VirtualStorage) List(ctx kapi.Context, label labels.Selector, field fie
55 55
 }
56 56
 
57 57
 func (m *VirtualStorage) Get(ctx kapi.Context, name string) (runtime.Object, error) {
58
-	policy, err := m.policyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
58
+	policy, err := m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
59 59
 	if err != nil && kapierrors.IsNotFound(err) {
60 60
 		return nil, kapierrors.NewNotFound("Role", name)
61 61
 	}
... ...
@@ -73,7 +76,7 @@ func (m *VirtualStorage) Get(ctx kapi.Context, name string) (runtime.Object, err
73 73
 
74 74
 // Delete(ctx api.Context, name string) (runtime.Object, error)
75 75
 func (m *VirtualStorage) Delete(ctx kapi.Context, name string, options *kapi.DeleteOptions) (runtime.Object, error) {
76
-	policy, err := m.policyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
76
+	policy, err := m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
77 77
 	if err != nil && kapierrors.IsNotFound(err) {
78 78
 		return nil, kapierrors.NewNotFound("Role", name)
79 79
 	}
... ...
@@ -88,14 +91,14 @@ func (m *VirtualStorage) Delete(ctx kapi.Context, name string, options *kapi.Del
88 88
 	delete(policy.Roles, name)
89 89
 	policy.LastModified = util.Now()
90 90
 
91
-	if err := m.policyStorage.UpdatePolicy(ctx, policy); err != nil {
91
+	if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil {
92 92
 		return nil, err
93 93
 	}
94 94
 	return &kapi.Status{Status: kapi.StatusSuccess}, nil
95 95
 }
96 96
 
97 97
 func (m *VirtualStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, error) {
98
-	if err := rest.BeforeCreate(roleregistry.Strategy, ctx, obj); err != nil {
98
+	if err := rest.BeforeCreate(m.CreateStrategy, ctx, obj); err != nil {
99 99
 		return nil, err
100 100
 	}
101 101
 
... ...
@@ -113,7 +116,7 @@ func (m *VirtualStorage) Create(ctx kapi.Context, obj runtime.Object) (runtime.O
113 113
 	policy.Roles[role.Name] = *role
114 114
 	policy.LastModified = util.Now()
115 115
 
116
-	if err := m.policyStorage.UpdatePolicy(ctx, policy); err != nil {
116
+	if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil {
117 117
 		return nil, err
118 118
 	}
119 119
 
... ...
@@ -131,11 +134,11 @@ func (m *VirtualStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.O
131 131
 		return nil, false, err
132 132
 	}
133 133
 
134
-	if err := rest.BeforeUpdate(roleregistry.Strategy, ctx, obj, old); err != nil {
134
+	if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, old); err != nil {
135 135
 		return nil, false, err
136 136
 	}
137 137
 
138
-	policy, err := m.policyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
138
+	policy, err := m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
139 139
 	if err != nil && kapierrors.IsNotFound(err) {
140 140
 		return nil, false, kapierrors.NewNotFound("Role", role.Name)
141 141
 	}
... ...
@@ -151,7 +154,7 @@ func (m *VirtualStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.O
151 151
 	policy.Roles[role.Name] = *role
152 152
 	policy.LastModified = util.Now()
153 153
 
154
-	if err := m.policyStorage.UpdatePolicy(ctx, policy); err != nil {
154
+	if err := m.PolicyStorage.UpdatePolicy(ctx, policy); err != nil {
155 155
 		return nil, false, err
156 156
 	}
157 157
 	return role, false, nil
... ...
@@ -160,7 +163,7 @@ func (m *VirtualStorage) Update(ctx kapi.Context, obj runtime.Object) (runtime.O
160 160
 // EnsurePolicy returns the policy object for the specified namespace.  If one does not exist, it is created for you.  Permission to
161 161
 // create, update, or delete roles in a namespace implies the ability to create a Policy object itself.
162 162
 func (m *VirtualStorage) EnsurePolicy(ctx kapi.Context) (*authorizationapi.Policy, error) {
163
-	policy, err := m.policyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
163
+	policy, err := m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
164 164
 	if err != nil {
165 165
 		if !kapierrors.IsNotFound(err) {
166 166
 			return nil, err
... ...
@@ -168,11 +171,11 @@ func (m *VirtualStorage) EnsurePolicy(ctx kapi.Context) (*authorizationapi.Polic
168 168
 
169 169
 		// if we have no policy, go ahead and make one.  creating one here collapses code paths below.  We only take this hit once
170 170
 		policy = NewEmptyPolicy(kapi.NamespaceValue(ctx))
171
-		if err := m.policyStorage.CreatePolicy(ctx, policy); err != nil {
171
+		if err := m.PolicyStorage.CreatePolicy(ctx, policy); err != nil {
172 172
 			return nil, err
173 173
 		}
174 174
 
175
-		policy, err = m.policyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
175
+		policy, err = m.PolicyStorage.GetPolicy(ctx, authorizationapi.PolicyName)
176 176
 		if err != nil {
177 177
 			return nil, err
178 178
 		}
... ...
@@ -9,16 +9,16 @@ import (
9 9
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
10 10
 
11 11
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
12
+	clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
12 13
 	roleregistry "github.com/openshift/origin/pkg/authorization/registry/role"
13 14
 	"github.com/openshift/origin/pkg/authorization/registry/test"
14
-	"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
15 15
 )
16 16
 
17
-func testNewBasePolicies() []authorizationapi.Policy {
18
-	return []authorizationapi.Policy{
17
+func testNewClusterPolicies() []authorizationapi.ClusterPolicy {
18
+	return []authorizationapi.ClusterPolicy{
19 19
 		{
20
-			ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.PolicyName, Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
21
-			Roles: map[string]authorizationapi.Role{
20
+			ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.PolicyName},
21
+			Roles: map[string]authorizationapi.ClusterRole{
22 22
 				"cluster-admin": {
23 23
 					ObjectMeta: kapi.ObjectMeta{Name: "cluster-admin"},
24 24
 					Rules:      []authorizationapi.PolicyRule{{Verbs: util.NewStringSet("*"), Resources: util.NewStringSet("*")}},
... ...
@@ -29,6 +29,10 @@ func testNewBasePolicies() []authorizationapi.Policy {
29 29
 				},
30 30
 			},
31 31
 		},
32
+	}
33
+}
34
+func testNewLocalPolicies() []authorizationapi.Policy {
35
+	return []authorizationapi.Policy{
32 36
 		{
33 37
 			ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.PolicyName, Namespace: "unittest"},
34 38
 			Roles:      map[string]authorizationapi.Role{},
... ...
@@ -36,14 +40,18 @@ func testNewBasePolicies() []authorizationapi.Policy {
36 36
 	}
37 37
 }
38 38
 
39
-func makeTestStorage() roleregistry.Storage {
40
-	policyRegistry := test.NewPolicyRegistry(testNewBasePolicies(), nil)
41
-
39
+func makeLocalTestStorage() roleregistry.Storage {
40
+	policyRegistry := test.NewPolicyRegistry(testNewLocalPolicies(), nil)
42 41
 	return NewVirtualStorage(policyRegistry)
43 42
 }
44 43
 
44
+func makeClusterTestStorage() roleregistry.Storage {
45
+	clusterPolicyRegistry := test.NewClusterPolicyRegistry(testNewClusterPolicies(), nil)
46
+	return NewVirtualStorage(clusterpolicyregistry.NewSimulatedRegistry(clusterPolicyRegistry))
47
+}
48
+
45 49
 func TestCreateValidationError(t *testing.T) {
46
-	storage := makeTestStorage()
50
+	storage := makeLocalTestStorage()
47 51
 
48 52
 	role := &authorizationapi.Role{}
49 53
 
... ...
@@ -55,7 +63,7 @@ func TestCreateValidationError(t *testing.T) {
55 55
 }
56 56
 
57 57
 func TestCreateValid(t *testing.T) {
58
-	storage := makeTestStorage()
58
+	storage := makeLocalTestStorage()
59 59
 
60 60
 	role := &authorizationapi.Role{
61 61
 		ObjectMeta: kapi.ObjectMeta{Name: "my-role"},
... ...
@@ -78,7 +86,7 @@ func TestCreateValid(t *testing.T) {
78 78
 }
79 79
 
80 80
 func TestUpdate(t *testing.T) {
81
-	storage := makeTestStorage()
81
+	storage := makeLocalTestStorage()
82 82
 	ctx := kapi.WithNamespace(kapi.NewContext(), "unittest")
83 83
 	realizedRoleObj, _ := storage.Create(ctx, &authorizationapi.Role{
84 84
 		ObjectMeta: kapi.ObjectMeta{Name: "my-role"},
... ...
@@ -109,7 +117,7 @@ func TestUpdate(t *testing.T) {
109 109
 }
110 110
 
111 111
 func TestUpdateError(t *testing.T) {
112
-	storage := makeTestStorage()
112
+	storage := makeLocalTestStorage()
113 113
 
114 114
 	role := &authorizationapi.Role{
115 115
 		ObjectMeta: kapi.ObjectMeta{Name: "my-role"},
... ...
@@ -127,7 +135,7 @@ func TestUpdateError(t *testing.T) {
127 127
 }
128 128
 
129 129
 func TestDeleteError(t *testing.T) {
130
-	storage := makeTestStorage()
130
+	storage := makeLocalTestStorage()
131 131
 
132 132
 	ctx := kapi.WithNamespace(kapi.NewContext(), "unittest")
133 133
 	_, err := storage.Delete(ctx, "foo", nil)
... ...
@@ -141,7 +149,7 @@ func TestDeleteError(t *testing.T) {
141 141
 }
142 142
 
143 143
 func TestDeleteValid(t *testing.T) {
144
-	storage := makeTestStorage()
144
+	storage := makeLocalTestStorage()
145 145
 	ctx := kapi.WithNamespace(kapi.NewContext(), "unittest")
146 146
 	storage.Create(ctx, &authorizationapi.Role{
147 147
 		ObjectMeta: kapi.ObjectMeta{Name: "my-role"},
... ...
@@ -16,44 +16,46 @@ import (
16 16
 
17 17
 // strategy implements behavior for nodes
18 18
 type strategy struct {
19
+	namespaced bool
19 20
 	runtime.ObjectTyper
20 21
 }
21 22
 
22 23
 // Strategy is the default logic that applies when creating and updating Role objects.
23
-var Strategy = strategy{kapi.Scheme}
24
+var ClusterStrategy = strategy{false, kapi.Scheme}
25
+var LocalStrategy = strategy{true, kapi.Scheme}
24 26
 
25 27
 // NamespaceScoped is false for policies.
26
-func (strategy) NamespaceScoped() bool {
27
-	return true
28
+func (s strategy) NamespaceScoped() bool {
29
+	return s.namespaced
28 30
 }
29 31
 
30 32
 // AllowCreateOnUpdate is false for policies.
31
-func (strategy) AllowCreateOnUpdate() bool {
33
+func (s strategy) AllowCreateOnUpdate() bool {
32 34
 	return false
33 35
 }
34 36
 
35
-func (strategy) GenerateName(base string) string {
37
+func (s strategy) GenerateName(base string) string {
36 38
 	return base
37 39
 }
38 40
 
39 41
 // PrepareForCreate clears fields that are not allowed to be set by end users on creation.
40
-func (strategy) PrepareForCreate(obj runtime.Object) {
42
+func (s strategy) PrepareForCreate(obj runtime.Object) {
41 43
 	_ = obj.(*authorizationapi.Role)
42 44
 }
43 45
 
44 46
 // PrepareForUpdate clears fields that are not allowed to be set by end users on update.
45
-func (strategy) PrepareForUpdate(obj, old runtime.Object) {
47
+func (s strategy) PrepareForUpdate(obj, old runtime.Object) {
46 48
 	_ = obj.(*authorizationapi.Role)
47 49
 }
48 50
 
49 51
 // Validate validates a new role.
50
-func (strategy) Validate(ctx kapi.Context, obj runtime.Object) fielderrors.ValidationErrorList {
51
-	return validation.ValidateRole(obj.(*authorizationapi.Role))
52
+func (s strategy) Validate(ctx kapi.Context, obj runtime.Object) fielderrors.ValidationErrorList {
53
+	return validation.ValidateRole(obj.(*authorizationapi.Role), s.namespaced)
52 54
 }
53 55
 
54 56
 // ValidateUpdate is the default update validation for an end user.
55
-func (strategy) ValidateUpdate(ctx kapi.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
56
-	return validation.ValidateRoleUpdate(obj.(*authorizationapi.Role), old.(*authorizationapi.Role))
57
+func (s strategy) ValidateUpdate(ctx kapi.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
58
+	return validation.ValidateRoleUpdate(obj.(*authorizationapi.Role), old.(*authorizationapi.Role), s.namespaced)
57 59
 }
58 60
 
59 61
 // Matcher returns a generic matcher for a given label and field selector.
... ...
@@ -13,6 +13,8 @@ import (
13 13
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
14 14
 
15 15
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
16
+	clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
17
+	clusterpolicybindingregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding"
16 18
 	policyregistry "github.com/openshift/origin/pkg/authorization/registry/policy"
17 19
 	policybindingregistry "github.com/openshift/origin/pkg/authorization/registry/policybinding"
18 20
 	rolebindingregistry "github.com/openshift/origin/pkg/authorization/registry/rolebinding"
... ...
@@ -20,14 +22,26 @@ import (
20 20
 )
21 21
 
22 22
 type VirtualStorage struct {
23
-	policyRegistry               policyregistry.Registry
24
-	bindingRegistry              policybindingregistry.Registry
25
-	masterAuthorizationNamespace string
23
+	PolicyRegistry               policyregistry.Registry
24
+	BindingRegistry              policybindingregistry.Registry
25
+	ClusterPolicyRegistry        clusterpolicyregistry.Registry
26
+	ClusterPolicyBindingRegistry clusterpolicybindingregistry.Registry
27
+
28
+	CreateStrategy rest.RESTCreateStrategy
29
+	UpdateStrategy rest.RESTUpdateStrategy
26 30
 }
27 31
 
28 32
 // NewVirtualStorage creates a new REST for policies.
29
-func NewVirtualStorage(policyRegistry policyregistry.Registry, bindingRegistry policybindingregistry.Registry, masterAuthorizationNamespace string) rolebindingregistry.Storage {
30
-	return &VirtualStorage{policyRegistry, bindingRegistry, masterAuthorizationNamespace}
33
+func NewVirtualStorage(policyRegistry policyregistry.Registry, bindingRegistry policybindingregistry.Registry, clusterPolicyRegistry clusterpolicyregistry.Registry, clusterPolicyBindingRegistry clusterpolicybindingregistry.Registry) rolebindingregistry.Storage {
34
+	return &VirtualStorage{
35
+		PolicyRegistry:               policyRegistry,
36
+		BindingRegistry:              bindingRegistry,
37
+		ClusterPolicyRegistry:        clusterPolicyRegistry,
38
+		ClusterPolicyBindingRegistry: clusterPolicyBindingRegistry,
39
+
40
+		CreateStrategy: rolebindingregistry.LocalStrategy,
41
+		UpdateStrategy: rolebindingregistry.LocalStrategy,
42
+	}
31 43
 }
32 44
 
33 45
 func (m *VirtualStorage) New() runtime.Object {
... ...
@@ -39,7 +53,7 @@ func (m *VirtualStorage) NewList() runtime.Object {
39 39
 
40 40
 // TODO either add selector for fields ot eliminate the option
41 41
 func (m *VirtualStorage) List(ctx kapi.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
42
-	policyBindingList, err := m.bindingRegistry.ListPolicyBindings(ctx, labels.Everything(), fields.Everything())
42
+	policyBindingList, err := m.BindingRegistry.ListPolicyBindings(ctx, labels.Everything(), fields.Everything())
43 43
 	if err != nil {
44 44
 		return nil, err
45 45
 	}
... ...
@@ -89,7 +103,7 @@ func (m *VirtualStorage) Delete(ctx kapi.Context, name string, options *kapi.Del
89 89
 	delete(owningPolicyBinding.RoleBindings, name)
90 90
 	owningPolicyBinding.LastModified = util.Now()
91 91
 
92
-	if err := m.bindingRegistry.UpdatePolicyBinding(ctx, owningPolicyBinding); err != nil {
92
+	if err := m.BindingRegistry.UpdatePolicyBinding(ctx, owningPolicyBinding); err != nil {
93 93
 		return nil, err
94 94
 	}
95 95
 
... ...
@@ -105,7 +119,7 @@ func (m *VirtualStorage) CreateRoleBindingWithEscalation(ctx kapi.Context, obj *
105 105
 }
106 106
 
107 107
 func (m *VirtualStorage) createRoleBinding(ctx kapi.Context, obj runtime.Object, allowEscalation bool) (*authorizationapi.RoleBinding, error) {
108
-	if err := rest.BeforeCreate(rolebindingregistry.Strategy, ctx, obj); err != nil {
108
+	if err := rest.BeforeCreate(m.CreateStrategy, ctx, obj); err != nil {
109 109
 		return nil, err
110 110
 	}
111 111
 
... ...
@@ -122,6 +136,7 @@ func (m *VirtualStorage) createRoleBinding(ctx kapi.Context, obj runtime.Object,
122 122
 
123 123
 	policyBinding, err := m.getPolicyBindingForPolicy(ctx, roleBinding.RoleRef.Namespace, allowEscalation)
124 124
 	if err != nil {
125
+		fmt.Printf("#### 1\n")
125 126
 		return nil, err
126 127
 	}
127 128
 
... ...
@@ -134,7 +149,7 @@ func (m *VirtualStorage) createRoleBinding(ctx kapi.Context, obj runtime.Object,
134 134
 	policyBinding.RoleBindings[roleBinding.Name] = *roleBinding
135 135
 	policyBinding.LastModified = util.Now()
136 136
 
137
-	if err := m.bindingRegistry.UpdatePolicyBinding(ctx, policyBinding); err != nil {
137
+	if err := m.BindingRegistry.UpdatePolicyBinding(ctx, policyBinding); err != nil {
138 138
 		return nil, err
139 139
 	}
140 140
 
... ...
@@ -159,7 +174,7 @@ func (m *VirtualStorage) updateRoleBinding(ctx kapi.Context, obj runtime.Object,
159 159
 		return nil, false, err
160 160
 	}
161 161
 
162
-	if err := rest.BeforeUpdate(rolebindingregistry.Strategy, ctx, obj, old); err != nil {
162
+	if err := rest.BeforeUpdate(m.UpdateStrategy, ctx, obj, old); err != nil {
163 163
 		return nil, false, err
164 164
 	}
165 165
 
... ...
@@ -189,7 +204,7 @@ func (m *VirtualStorage) updateRoleBinding(ctx kapi.Context, obj runtime.Object,
189 189
 	policyBinding.RoleBindings[roleBinding.Name] = *roleBinding
190 190
 	policyBinding.LastModified = util.Now()
191 191
 
192
-	if err := m.bindingRegistry.UpdatePolicyBinding(ctx, policyBinding); err != nil {
192
+	if err := m.BindingRegistry.UpdatePolicyBinding(ctx, policyBinding); err != nil {
193 193
 		return nil, false, err
194 194
 	}
195 195
 	return roleBinding, false, nil
... ...
@@ -206,7 +221,17 @@ func (m *VirtualStorage) validateReferentialIntegrity(ctx kapi.Context, roleBind
206 206
 func (m *VirtualStorage) getReferencedRole(roleRef kapi.ObjectReference) (*authorizationapi.Role, error) {
207 207
 	ctx := kapi.WithNamespace(kapi.NewContext(), roleRef.Namespace)
208 208
 
209
-	policy, err := m.policyRegistry.GetPolicy(ctx, authorizationapi.PolicyName)
209
+	var policy *authorizationapi.Policy
210
+	var err error
211
+	switch {
212
+	case len(roleRef.Namespace) == 0:
213
+		var clusterPolicy *authorizationapi.ClusterPolicy
214
+		clusterPolicy, err = m.ClusterPolicyRegistry.GetClusterPolicy(ctx, authorizationapi.PolicyName)
215
+		policy = authorizationapi.ToPolicy(clusterPolicy)
216
+	default:
217
+		policy, err = m.PolicyRegistry.GetPolicy(ctx, authorizationapi.PolicyName)
218
+	}
219
+
210 220
 	if err != nil {
211 221
 		return nil, err
212 222
 	}
... ...
@@ -225,12 +250,17 @@ func (m *VirtualStorage) confirmNoEscalation(ctx kapi.Context, roleBinding *auth
225 225
 		return err
226 226
 	}
227 227
 
228
-	ruleResolver := rulevalidation.NewDefaultRuleResolver(m.policyRegistry, m.bindingRegistry)
228
+	ruleResolver := rulevalidation.NewDefaultRuleResolver(
229
+		m.PolicyRegistry,
230
+		m.BindingRegistry,
231
+		clusterpolicyregistry.NewSimulatedRegistry(m.ClusterPolicyRegistry),
232
+		clusterpolicybindingregistry.NewSimulatedRegistry(m.ClusterPolicyBindingRegistry),
233
+	)
229 234
 	ownerLocalRules, err := ruleResolver.GetEffectivePolicyRules(ctx)
230 235
 	if err != nil {
231 236
 		return err
232 237
 	}
233
-	masterContext := kapi.WithNamespace(ctx, m.masterAuthorizationNamespace)
238
+	masterContext := kapi.WithNamespace(ctx, "")
234 239
 	ownerGlobalRules, err := ruleResolver.GetEffectivePolicyRules(masterContext)
235 240
 	if err != nil {
236 241
 		return err
... ...
@@ -251,7 +281,7 @@ func (m *VirtualStorage) confirmNoEscalation(ctx kapi.Context, roleBinding *auth
251 251
 
252 252
 // ensurePolicyBindingToMaster returns a PolicyBinding object that has a PolicyRef pointing to the Policy in the passed namespace.
253 253
 func (m *VirtualStorage) ensurePolicyBindingToMaster(ctx kapi.Context, policyNamespace, policyBindingName string) (*authorizationapi.PolicyBinding, error) {
254
-	policyBinding, err := m.bindingRegistry.GetPolicyBinding(ctx, policyBindingName)
254
+	policyBinding, err := m.BindingRegistry.GetPolicyBinding(ctx, policyBindingName)
255 255
 	if err != nil {
256 256
 		if !kapierrors.IsNotFound(err) {
257 257
 			return nil, err
... ...
@@ -259,11 +289,11 @@ func (m *VirtualStorage) ensurePolicyBindingToMaster(ctx kapi.Context, policyNam
259 259
 
260 260
 		// if we have no policyBinding, go ahead and make one.  creating one here collapses code paths below.  We only take this hit once
261 261
 		policyBinding = policybindingregistry.NewEmptyPolicyBinding(kapi.NamespaceValue(ctx), policyNamespace, policyBindingName)
262
-		if err := m.bindingRegistry.CreatePolicyBinding(ctx, policyBinding); err != nil {
262
+		if err := m.BindingRegistry.CreatePolicyBinding(ctx, policyBinding); err != nil {
263 263
 			return nil, err
264 264
 		}
265 265
 
266
-		policyBinding, err = m.bindingRegistry.GetPolicyBinding(ctx, policyBindingName)
266
+		policyBinding, err = m.BindingRegistry.GetPolicyBinding(ctx, policyBindingName)
267 267
 		if err != nil {
268 268
 			return nil, err
269 269
 		}
... ...
@@ -280,11 +310,11 @@ func (m *VirtualStorage) ensurePolicyBindingToMaster(ctx kapi.Context, policyNam
280 280
 func (m *VirtualStorage) getPolicyBindingForPolicy(ctx kapi.Context, policyNamespace string, allowAutoProvision bool) (*authorizationapi.PolicyBinding, error) {
281 281
 	// we can autocreate a PolicyBinding object if the RoleBinding is for the master namespace OR if we've been explicity told to create the policying binding.
282 282
 	// the latter happens during priming
283
-	if (policyNamespace == m.masterAuthorizationNamespace) || allowAutoProvision {
283
+	if (policyNamespace == "") || allowAutoProvision {
284 284
 		return m.ensurePolicyBindingToMaster(ctx, policyNamespace, authorizationapi.GetPolicyBindingName(policyNamespace))
285 285
 	}
286 286
 
287
-	policyBinding, err := m.bindingRegistry.GetPolicyBinding(ctx, authorizationapi.GetPolicyBindingName(policyNamespace))
287
+	policyBinding, err := m.BindingRegistry.GetPolicyBinding(ctx, authorizationapi.GetPolicyBindingName(policyNamespace))
288 288
 	if err != nil {
289 289
 		return nil, err
290 290
 	}
... ...
@@ -297,7 +327,7 @@ func (m *VirtualStorage) getPolicyBindingForPolicy(ctx kapi.Context, policyNames
297 297
 }
298 298
 
299 299
 func (m *VirtualStorage) getPolicyBindingOwningRoleBinding(ctx kapi.Context, bindingName string) (*authorizationapi.PolicyBinding, error) {
300
-	policyBindingList, err := m.bindingRegistry.ListPolicyBindings(ctx, labels.Everything(), fields.Everything())
300
+	policyBindingList, err := m.BindingRegistry.ListPolicyBindings(ctx, labels.Everything(), fields.Everything())
301 301
 	if err != nil {
302 302
 		return nil, err
303 303
 	}
... ...
@@ -12,36 +12,17 @@ import (
12 12
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
13 13
 
14 14
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
15
+	clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
16
+	clusterpolicybindingregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding"
15 17
 	rolebindingregistry "github.com/openshift/origin/pkg/authorization/registry/rolebinding"
16 18
 	"github.com/openshift/origin/pkg/authorization/registry/test"
17
-	"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
18 19
 )
19 20
 
20
-func testNewBaseBindings() []authorizationapi.PolicyBinding {
21
-	return []authorizationapi.PolicyBinding{
21
+func testNewClusterPolicies() []authorizationapi.ClusterPolicy {
22
+	return []authorizationapi.ClusterPolicy{
22 23
 		{
23
-			ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.GetPolicyBindingName(bootstrappolicy.DefaultMasterAuthorizationNamespace), Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
24
-			PolicyRef:  kapi.ObjectReference{Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
25
-			RoleBindings: map[string]authorizationapi.RoleBinding{
26
-				"cluster-admins": {
27
-					ObjectMeta: kapi.ObjectMeta{Name: "cluster-admins"},
28
-					RoleRef:    kapi.ObjectReference{Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace, Name: "cluster-admin"},
29
-					Users:      util.NewStringSet("system:admin"),
30
-				},
31
-			},
32
-		},
33
-		{
34
-			ObjectMeta:   kapi.ObjectMeta{Name: authorizationapi.GetPolicyBindingName(bootstrappolicy.DefaultMasterAuthorizationNamespace), Namespace: "unittest"},
35
-			PolicyRef:    kapi.ObjectReference{Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
36
-			RoleBindings: map[string]authorizationapi.RoleBinding{},
37
-		},
38
-	}
39
-}
40
-func testNewBasePolicies() []authorizationapi.Policy {
41
-	return []authorizationapi.Policy{
42
-		{
43
-			ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.PolicyName, Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
44
-			Roles: map[string]authorizationapi.Role{
24
+			ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.PolicyName},
25
+			Roles: map[string]authorizationapi.ClusterRole{
45 26
 				"cluster-admin": {
46 27
 					ObjectMeta: kapi.ObjectMeta{Name: "cluster-admin"},
47 28
 					Rules:      []authorizationapi.PolicyRule{{Verbs: util.NewStringSet("*"), Resources: util.NewStringSet("*")}},
... ...
@@ -55,11 +36,43 @@ func testNewBasePolicies() []authorizationapi.Policy {
55 55
 	}
56 56
 }
57 57
 
58
+func testNewClusterBindings() []authorizationapi.ClusterPolicyBinding {
59
+	return []authorizationapi.ClusterPolicyBinding{
60
+		{
61
+			ObjectMeta: kapi.ObjectMeta{Name: authorizationapi.ClusterPolicyBindingName},
62
+			RoleBindings: map[string]authorizationapi.ClusterRoleBinding{
63
+				"cluster-admins": {
64
+					ObjectMeta: kapi.ObjectMeta{Name: "cluster-admins"},
65
+					RoleRef:    kapi.ObjectReference{Name: "cluster-admin"},
66
+					Users:      util.NewStringSet("system:admin"),
67
+				},
68
+			},
69
+		},
70
+	}
71
+}
72
+func testNewLocalBindings() []authorizationapi.PolicyBinding {
73
+	return []authorizationapi.PolicyBinding{
74
+		{
75
+			ObjectMeta:   kapi.ObjectMeta{Name: authorizationapi.GetPolicyBindingName("unittest"), Namespace: "unittest"},
76
+			RoleBindings: map[string]authorizationapi.RoleBinding{},
77
+		},
78
+	}
79
+}
80
+
58 81
 func makeTestStorage() rolebindingregistry.Storage {
59
-	bindingRegistry := test.NewPolicyBindingRegistry(testNewBaseBindings(), nil)
60
-	policyRegistry := test.NewPolicyRegistry(testNewBasePolicies(), nil)
82
+	clusterBindingRegistry := test.NewClusterPolicyBindingRegistry(testNewClusterBindings(), nil)
83
+	bindingRegistry := test.NewPolicyBindingRegistry(testNewLocalBindings(), nil)
84
+	clusterPolicyRegistry := test.NewClusterPolicyRegistry(testNewClusterPolicies(), nil)
85
+	policyRegistry := test.NewPolicyRegistry([]authorizationapi.Policy{}, nil)
61 86
 
62
-	return NewVirtualStorage(policyRegistry, bindingRegistry, bootstrappolicy.DefaultMasterAuthorizationNamespace)
87
+	return NewVirtualStorage(policyRegistry, bindingRegistry, clusterPolicyRegistry, clusterBindingRegistry)
88
+}
89
+
90
+func makeClusterTestStorage() rolebindingregistry.Storage {
91
+	clusterBindingRegistry := test.NewClusterPolicyBindingRegistry(testNewClusterBindings(), nil)
92
+	clusterPolicyRegistry := test.NewClusterPolicyRegistry(testNewClusterPolicies(), nil)
93
+
94
+	return NewVirtualStorage(clusterpolicyregistry.NewSimulatedRegistry(clusterPolicyRegistry), clusterpolicybindingregistry.NewSimulatedRegistry(clusterBindingRegistry), clusterPolicyRegistry, clusterBindingRegistry)
63 95
 }
64 96
 
65 97
 func TestCreateValidationError(t *testing.T) {
... ...
@@ -77,7 +90,7 @@ func TestCreateValidAutoCreateMasterPolicyBindings(t *testing.T) {
77 77
 	storage := makeTestStorage()
78 78
 	roleBinding := &authorizationapi.RoleBinding{
79 79
 		ObjectMeta: kapi.ObjectMeta{Name: "my-roleBinding"},
80
-		RoleRef:    kapi.ObjectReference{Name: "admin", Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
80
+		RoleRef:    kapi.ObjectReference{Name: "admin"},
81 81
 	}
82 82
 
83 83
 	ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "unittest"), &user.DefaultInfo{Name: "system:admin"})
... ...
@@ -103,7 +116,7 @@ func TestCreateValid(t *testing.T) {
103 103
 
104 104
 	roleBinding := &authorizationapi.RoleBinding{
105 105
 		ObjectMeta: kapi.ObjectMeta{Name: "my-roleBinding"},
106
-		RoleRef:    kapi.ObjectReference{Name: "admin", Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
106
+		RoleRef:    kapi.ObjectReference{Name: "admin"},
107 107
 	}
108 108
 
109 109
 	obj, err := storage.Create(ctx, roleBinding)
... ...
@@ -127,7 +140,7 @@ func TestUpdate(t *testing.T) {
127 127
 	storage := makeTestStorage()
128 128
 	obj, err := storage.Create(ctx, &authorizationapi.RoleBinding{
129 129
 		ObjectMeta: kapi.ObjectMeta{Name: "my-roleBinding"},
130
-		RoleRef:    kapi.ObjectReference{Name: "admin", Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
130
+		RoleRef:    kapi.ObjectReference{Name: "admin"},
131 131
 	})
132 132
 	if err != nil {
133 133
 		t.Errorf("unexpected error: %v", err)
... ...
@@ -137,7 +150,7 @@ func TestUpdate(t *testing.T) {
137 137
 
138 138
 	roleBinding := &authorizationapi.RoleBinding{
139 139
 		ObjectMeta: kapi.ObjectMeta{Name: "my-roleBinding", ResourceVersion: original.ResourceVersion},
140
-		RoleRef:    kapi.ObjectReference{Name: "admin", Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
140
+		RoleRef:    kapi.ObjectReference{Name: "admin"},
141 141
 	}
142 142
 
143 143
 	obj, created, err := storage.Update(ctx, roleBinding)
... ...
@@ -165,7 +178,7 @@ func TestUpdateError(t *testing.T) {
165 165
 	storage := makeTestStorage()
166 166
 	obj, err := storage.Create(ctx, &authorizationapi.RoleBinding{
167 167
 		ObjectMeta: kapi.ObjectMeta{Name: "my-different"},
168
-		RoleRef:    kapi.ObjectReference{Name: "admin", Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
168
+		RoleRef:    kapi.ObjectReference{Name: "admin"},
169 169
 	})
170 170
 	if err != nil {
171 171
 		t.Errorf("unexpected error: %v", err)
... ...
@@ -175,7 +188,7 @@ func TestUpdateError(t *testing.T) {
175 175
 
176 176
 	roleBinding := &authorizationapi.RoleBinding{
177 177
 		ObjectMeta: kapi.ObjectMeta{Name: "my-roleBinding", ResourceVersion: original.ResourceVersion},
178
-		RoleRef:    kapi.ObjectReference{Name: "admin", Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
178
+		RoleRef:    kapi.ObjectReference{Name: "admin"},
179 179
 	}
180 180
 
181 181
 	_, _, err = storage.Update(ctx, roleBinding)
... ...
@@ -194,7 +207,7 @@ func TestUpdateCannotChangeRoleRefError(t *testing.T) {
194 194
 	storage := makeTestStorage()
195 195
 	obj, err := storage.Create(ctx, &authorizationapi.RoleBinding{
196 196
 		ObjectMeta: kapi.ObjectMeta{Name: "my-different"},
197
-		RoleRef:    kapi.ObjectReference{Name: "admin", Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
197
+		RoleRef:    kapi.ObjectReference{Name: "admin"},
198 198
 	})
199 199
 	if err != nil {
200 200
 		t.Errorf("unexpected error: %v", err)
... ...
@@ -204,7 +217,7 @@ func TestUpdateCannotChangeRoleRefError(t *testing.T) {
204 204
 
205 205
 	roleBinding := &authorizationapi.RoleBinding{
206 206
 		ObjectMeta: kapi.ObjectMeta{Name: "my-different", ResourceVersion: original.ResourceVersion},
207
-		RoleRef:    kapi.ObjectReference{Name: "cluster-admin", Namespace: bootstrappolicy.DefaultMasterAuthorizationNamespace},
207
+		RoleRef:    kapi.ObjectReference{Name: "cluster-admin"},
208 208
 	}
209 209
 
210 210
 	_, _, err = storage.Update(ctx, roleBinding)
... ...
@@ -219,23 +232,22 @@ func TestUpdateCannotChangeRoleRefError(t *testing.T) {
219 219
 }
220 220
 
221 221
 func TestDeleteError(t *testing.T) {
222
-	registry := &test.PolicyBindingRegistry{}
222
+	bindingRegistry := &test.PolicyBindingRegistry{}
223
+	bindingRegistry.Err = errors.New("Sample Error")
223 224
 
224
-	registry.Err = errors.New("Sample Error")
225
-	policyRegistry := &test.PolicyRegistry{}
226
-	storage := NewVirtualStorage(policyRegistry, registry, bootstrappolicy.DefaultMasterAuthorizationNamespace)
225
+	storage := NewVirtualStorage(&test.PolicyRegistry{}, bindingRegistry, &test.ClusterPolicyRegistry{}, &test.ClusterPolicyBindingRegistry{})
227 226
 
228 227
 	ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), "unittest"), &user.DefaultInfo{Name: "system:admin"})
229 228
 	_, err := storage.Delete(ctx, "foo", nil)
230
-	if err != registry.Err {
229
+	if err != bindingRegistry.Err {
231 230
 		t.Errorf("unexpected error: %v", err)
232 231
 	}
233 232
 }
234 233
 
235 234
 func TestDeleteValid(t *testing.T) {
236
-	storage := makeTestStorage()
235
+	storage := makeClusterTestStorage()
237 236
 
238
-	ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), bootstrappolicy.DefaultMasterAuthorizationNamespace), &user.DefaultInfo{Name: "system:admin"})
237
+	ctx := kapi.WithUser(kapi.WithNamespace(kapi.NewContext(), ""), &user.DefaultInfo{Name: "system:admin"})
239 238
 	obj, err := storage.Delete(ctx, "cluster-admins", nil)
240 239
 	if err != nil {
241 240
 		t.Fatalf("unexpected error: %v", err)
... ...
@@ -17,44 +17,46 @@ import (
17 17
 
18 18
 // strategy implements behavior for nodes
19 19
 type strategy struct {
20
+	namespaced bool
21
+
20 22
 	runtime.ObjectTyper
21 23
 }
22 24
 
23
-// Strategy is the default logic that applies when creating and updating rolebindings.
24
-var Strategy = strategy{kapi.Scheme}
25
+var ClusterStrategy = strategy{false, kapi.Scheme}
26
+var LocalStrategy = strategy{true, kapi.Scheme}
25 27
 
26 28
 // NamespaceScoped is false for rolebindings.
27
-func (strategy) NamespaceScoped() bool {
28
-	return true
29
+func (s strategy) NamespaceScoped() bool {
30
+	return s.namespaced
29 31
 }
30 32
 
31 33
 // AllowCreateOnUpdate is false for rolebindings.
32
-func (strategy) AllowCreateOnUpdate() bool {
34
+func (s strategy) AllowCreateOnUpdate() bool {
33 35
 	return false
34 36
 }
35 37
 
36
-func (strategy) GenerateName(base string) string {
38
+func (s strategy) GenerateName(base string) string {
37 39
 	return base
38 40
 }
39 41
 
40 42
 // PrepareForCreate clears fields that are not allowed to be set by end users on creation.
41
-func (strategy) PrepareForCreate(obj runtime.Object) {
43
+func (s strategy) PrepareForCreate(obj runtime.Object) {
42 44
 	_ = obj.(*authorizationapi.RoleBinding)
43 45
 }
44 46
 
45 47
 // PrepareForUpdate clears fields that are not allowed to be set by end users on update.
46
-func (strategy) PrepareForUpdate(obj, old runtime.Object) {
48
+func (s strategy) PrepareForUpdate(obj, old runtime.Object) {
47 49
 	_ = obj.(*authorizationapi.RoleBinding)
48 50
 }
49 51
 
50 52
 // Validate validates a new role.
51
-func (strategy) Validate(ctx kapi.Context, obj runtime.Object) fielderrors.ValidationErrorList {
52
-	return validation.ValidateRoleBinding(obj.(*authorizationapi.RoleBinding))
53
+func (s strategy) Validate(ctx kapi.Context, obj runtime.Object) fielderrors.ValidationErrorList {
54
+	return validation.ValidateRoleBinding(obj.(*authorizationapi.RoleBinding), s.namespaced)
53 55
 }
54 56
 
55 57
 // ValidateUpdate is the default update validation for an end user.
56
-func (strategy) ValidateUpdate(ctx kapi.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
57
-	return validation.ValidateRoleBindingUpdate(obj.(*authorizationapi.RoleBinding), old.(*authorizationapi.RoleBinding))
58
+func (s strategy) ValidateUpdate(ctx kapi.Context, obj, old runtime.Object) fielderrors.ValidationErrorList {
59
+	return validation.ValidateRoleBindingUpdate(obj.(*authorizationapi.RoleBinding), old.(*authorizationapi.RoleBinding), s.namespaced)
58 60
 }
59 61
 
60 62
 // Matcher returns a generic matcher for a given label and field selector.
... ...
@@ -10,7 +10,6 @@ import (
10 10
 
11 11
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
12 12
 	"github.com/openshift/origin/pkg/authorization/authorizer"
13
-	"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
14 13
 )
15 14
 
16 15
 type subjectAccessTest struct {
... ...
@@ -67,7 +66,7 @@ func TestNoErrors(t *testing.T) {
67 67
 			reason:  "because good things",
68 68
 		},
69 69
 		reviewRequest: &authorizationapi.SubjectAccessReview{
70
-			Groups:   util.NewStringSet(bootstrappolicy.DefaultMasterAuthorizationNamespace),
70
+			Groups:   util.NewStringSet("not-master"),
71 71
 			Verb:     "delete",
72 72
 			Resource: "deploymentConfigs",
73 73
 		},
74 74
new file mode 100644
... ...
@@ -0,0 +1,156 @@
0
+package test
1
+
2
+import (
3
+	"errors"
4
+	"fmt"
5
+
6
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
7
+	kapierrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
8
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
9
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
10
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
11
+
12
+	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
13
+)
14
+
15
+var resourceVersion = 1
16
+
17
+type ClusterPolicyRegistry struct {
18
+	// ClusterPolicies is a of namespace->name->ClusterPolicy
19
+	ClusterPolicies map[string]map[string]authorizationapi.ClusterPolicy
20
+	Err             error
21
+}
22
+
23
+func NewClusterPolicyRegistry(policies []authorizationapi.ClusterPolicy, err error) *ClusterPolicyRegistry {
24
+	policyMap := make(map[string]map[string]authorizationapi.ClusterPolicy)
25
+
26
+	for _, policy := range policies {
27
+		addClusterPolicy(policyMap, policy)
28
+	}
29
+
30
+	return &ClusterPolicyRegistry{policyMap, err}
31
+}
32
+
33
+// ListClusterPolicies obtains list of ListClusterPolicy that match a selector.
34
+func (r *ClusterPolicyRegistry) ListClusterPolicies(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.ClusterPolicyList, error) {
35
+	if r.Err != nil {
36
+		return nil, r.Err
37
+	}
38
+
39
+	namespace := kapi.NamespaceValue(ctx)
40
+	list := make([]authorizationapi.ClusterPolicy, 0)
41
+
42
+	if namespace == kapi.NamespaceAll {
43
+		for _, curr := range r.ClusterPolicies {
44
+			for _, policy := range curr {
45
+				list = append(list, policy)
46
+			}
47
+		}
48
+
49
+	} else {
50
+		if namespacedClusterPolicies, ok := r.ClusterPolicies[namespace]; ok {
51
+			for _, curr := range namespacedClusterPolicies {
52
+				list = append(list, curr)
53
+			}
54
+		}
55
+	}
56
+
57
+	return &authorizationapi.ClusterPolicyList{
58
+			Items: list,
59
+		},
60
+		nil
61
+}
62
+
63
+// GetClusterPolicy retrieves a specific policy.
64
+func (r *ClusterPolicyRegistry) GetClusterPolicy(ctx kapi.Context, id string) (*authorizationapi.ClusterPolicy, error) {
65
+	if r.Err != nil {
66
+		return nil, r.Err
67
+	}
68
+
69
+	namespace := kapi.NamespaceValue(ctx)
70
+	if len(namespace) != 0 {
71
+		return nil, errors.New("invalid request.  Namespace parameter disallowed.")
72
+	}
73
+
74
+	if namespacedClusterPolicies, ok := r.ClusterPolicies[namespace]; ok {
75
+		if policy, ok := namespacedClusterPolicies[id]; ok {
76
+			return &policy, nil
77
+		}
78
+	}
79
+
80
+	return nil, kapierrors.NewNotFound("ClusterPolicy", id)
81
+}
82
+
83
+// CreateClusterPolicy creates a new policy.
84
+func (r *ClusterPolicyRegistry) CreateClusterPolicy(ctx kapi.Context, policy *authorizationapi.ClusterPolicy) error {
85
+	if r.Err != nil {
86
+		return r.Err
87
+	}
88
+
89
+	namespace := kapi.NamespaceValue(ctx)
90
+	if len(namespace) != 0 {
91
+		return errors.New("invalid request.  Namespace parameter disallowed.")
92
+	}
93
+	if existing, _ := r.GetClusterPolicy(ctx, policy.Name); existing != nil {
94
+		return kapierrors.NewAlreadyExists("ClusterPolicy", policy.Name)
95
+	}
96
+
97
+	addClusterPolicy(r.ClusterPolicies, *policy)
98
+
99
+	return nil
100
+}
101
+
102
+// UpdateClusterPolicy updates a policy.
103
+func (r *ClusterPolicyRegistry) UpdateClusterPolicy(ctx kapi.Context, policy *authorizationapi.ClusterPolicy) error {
104
+	if r.Err != nil {
105
+		return r.Err
106
+	}
107
+
108
+	namespace := kapi.NamespaceValue(ctx)
109
+	if len(namespace) != 0 {
110
+		return errors.New("invalid request.  Namespace parameter disallowed.")
111
+	}
112
+	if existing, _ := r.GetClusterPolicy(ctx, policy.Name); existing == nil {
113
+		return kapierrors.NewNotFound("ClusterPolicy", policy.Name)
114
+	}
115
+
116
+	addClusterPolicy(r.ClusterPolicies, *policy)
117
+
118
+	return nil
119
+}
120
+
121
+// DeleteClusterPolicy deletes a policy.
122
+func (r *ClusterPolicyRegistry) DeleteClusterPolicy(ctx kapi.Context, id string) error {
123
+	if r.Err != nil {
124
+		return r.Err
125
+	}
126
+
127
+	namespace := kapi.NamespaceValue(ctx)
128
+	if len(namespace) != 0 {
129
+		return errors.New("invalid request.  Namespace parameter disallowed.")
130
+	}
131
+
132
+	namespacedClusterPolicies, ok := r.ClusterPolicies[namespace]
133
+	if ok {
134
+		delete(namespacedClusterPolicies, id)
135
+	}
136
+
137
+	return nil
138
+}
139
+
140
+func (r *ClusterPolicyRegistry) WatchClusterPolicies(ctx kapi.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
141
+	return nil, errors.New("unsupported")
142
+}
143
+
144
+func addClusterPolicy(policies map[string]map[string]authorizationapi.ClusterPolicy, policy authorizationapi.ClusterPolicy) {
145
+	resourceVersion += 1
146
+	policy.ResourceVersion = fmt.Sprintf("%d", resourceVersion)
147
+
148
+	namespacedClusterPolicies, ok := policies[policy.Namespace]
149
+	if !ok {
150
+		namespacedClusterPolicies = make(map[string]authorizationapi.ClusterPolicy)
151
+		policies[policy.Namespace] = namespacedClusterPolicies
152
+	}
153
+
154
+	namespacedClusterPolicies[policy.Name] = policy
155
+}
0 156
new file mode 100644
... ...
@@ -0,0 +1,154 @@
0
+package test
1
+
2
+import (
3
+	"errors"
4
+	"fmt"
5
+
6
+	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
7
+	kapierrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
8
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
9
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
10
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
11
+
12
+	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
13
+)
14
+
15
+type ClusterPolicyBindingRegistry struct {
16
+	// ClusterPolicyBindings is a of namespace->name->ClusterPolicyBinding
17
+	ClusterPolicyBindings map[string]map[string]authorizationapi.ClusterPolicyBinding
18
+	Err                   error
19
+}
20
+
21
+func NewClusterPolicyBindingRegistry(bindings []authorizationapi.ClusterPolicyBinding, err error) *ClusterPolicyBindingRegistry {
22
+	bindingMap := make(map[string]map[string]authorizationapi.ClusterPolicyBinding)
23
+
24
+	for _, binding := range bindings {
25
+		addClusterPolicyBinding(bindingMap, binding)
26
+	}
27
+
28
+	return &ClusterPolicyBindingRegistry{bindingMap, err}
29
+}
30
+
31
+// ListClusterPolicies obtains list of ListClusterPolicyBinding that match a selector.
32
+func (r *ClusterPolicyBindingRegistry) ListClusterPolicyBindings(ctx kapi.Context, label labels.Selector, field fields.Selector) (*authorizationapi.ClusterPolicyBindingList, error) {
33
+	if r.Err != nil {
34
+		return nil, r.Err
35
+	}
36
+
37
+	namespace := kapi.NamespaceValue(ctx)
38
+	list := make([]authorizationapi.ClusterPolicyBinding, 0)
39
+
40
+	if namespace == kapi.NamespaceAll {
41
+		for _, curr := range r.ClusterPolicyBindings {
42
+			for _, binding := range curr {
43
+				list = append(list, binding)
44
+			}
45
+		}
46
+
47
+	} else {
48
+		if namespacedBindings, ok := r.ClusterPolicyBindings[namespace]; ok {
49
+			for _, curr := range namespacedBindings {
50
+				list = append(list, curr)
51
+			}
52
+		}
53
+	}
54
+
55
+	return &authorizationapi.ClusterPolicyBindingList{
56
+			Items: list,
57
+		},
58
+		nil
59
+}
60
+
61
+// GetClusterPolicyBinding retrieves a specific policyBinding.
62
+func (r *ClusterPolicyBindingRegistry) GetClusterPolicyBinding(ctx kapi.Context, id string) (*authorizationapi.ClusterPolicyBinding, error) {
63
+	if r.Err != nil {
64
+		return nil, r.Err
65
+	}
66
+
67
+	namespace := kapi.NamespaceValue(ctx)
68
+	if len(namespace) != 0 {
69
+		return nil, errors.New("invalid request.  Namespace parameter disallowed.")
70
+	}
71
+
72
+	if namespacedBindings, ok := r.ClusterPolicyBindings[namespace]; ok {
73
+		if binding, ok := namespacedBindings[id]; ok {
74
+			return &binding, nil
75
+		}
76
+	}
77
+
78
+	return nil, kapierrors.NewNotFound("ClusterPolicyBinding", id)
79
+}
80
+
81
+// CreateClusterPolicyBinding creates a new policyBinding.
82
+func (r *ClusterPolicyBindingRegistry) CreateClusterPolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.ClusterPolicyBinding) error {
83
+	if r.Err != nil {
84
+		return r.Err
85
+	}
86
+
87
+	namespace := kapi.NamespaceValue(ctx)
88
+	if len(namespace) != 0 {
89
+		return errors.New("invalid request.  Namespace parameter disallowed.")
90
+	}
91
+	if existing, _ := r.GetClusterPolicyBinding(ctx, policyBinding.Name); existing != nil {
92
+		return kapierrors.NewAlreadyExists("ClusterPolicyBinding", policyBinding.Name)
93
+	}
94
+
95
+	addClusterPolicyBinding(r.ClusterPolicyBindings, *policyBinding)
96
+
97
+	return nil
98
+}
99
+
100
+// UpdateClusterPolicyBinding updates a policyBinding.
101
+func (r *ClusterPolicyBindingRegistry) UpdateClusterPolicyBinding(ctx kapi.Context, policyBinding *authorizationapi.ClusterPolicyBinding) error {
102
+	if r.Err != nil {
103
+		return r.Err
104
+	}
105
+
106
+	namespace := kapi.NamespaceValue(ctx)
107
+	if len(namespace) != 0 {
108
+		return errors.New("invalid request.  Namespace parameter disallowed.")
109
+	}
110
+	if existing, _ := r.GetClusterPolicyBinding(ctx, policyBinding.Name); existing == nil {
111
+		return kapierrors.NewNotFound("ClusterPolicyBinding", policyBinding.Name)
112
+	}
113
+
114
+	addClusterPolicyBinding(r.ClusterPolicyBindings, *policyBinding)
115
+
116
+	return nil
117
+}
118
+
119
+// DeleteClusterPolicyBinding deletes a policyBinding.
120
+func (r *ClusterPolicyBindingRegistry) DeleteClusterPolicyBinding(ctx kapi.Context, id string) error {
121
+	if r.Err != nil {
122
+		return r.Err
123
+	}
124
+
125
+	namespace := kapi.NamespaceValue(ctx)
126
+	if len(namespace) != 0 {
127
+		return errors.New("invalid request.  Namespace parameter disallowed.")
128
+	}
129
+
130
+	namespacedBindings, ok := r.ClusterPolicyBindings[namespace]
131
+	if ok {
132
+		delete(namespacedBindings, id)
133
+	}
134
+
135
+	return nil
136
+}
137
+
138
+func (r *ClusterPolicyBindingRegistry) WatchClusterPolicyBindings(ctx kapi.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
139
+	return nil, errors.New("unsupported")
140
+}
141
+
142
+func addClusterPolicyBinding(bindings map[string]map[string]authorizationapi.ClusterPolicyBinding, binding authorizationapi.ClusterPolicyBinding) {
143
+	resourceVersion += 1
144
+	binding.ResourceVersion = fmt.Sprintf("%d", resourceVersion)
145
+
146
+	namespacedBindings, ok := bindings[binding.Namespace]
147
+	if !ok {
148
+		namespacedBindings = make(map[string]authorizationapi.ClusterPolicyBinding)
149
+		bindings[binding.Namespace] = namespacedBindings
150
+	}
151
+
152
+	namespacedBindings[binding.Name] = binding
153
+}
... ...
@@ -12,8 +12,6 @@ import (
12 12
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
13 13
 )
14 14
 
15
-var resourceVersion = 1
16
-
17 15
 type PolicyRegistry struct {
18 16
 	// Policies is a of namespace->name->Policy
19 17
 	Policies map[string]map[string]authorizationapi.Policy
... ...
@@ -5,6 +5,7 @@ import (
5 5
 	"fmt"
6 6
 
7 7
 	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
8
+	kapierrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
8 9
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
9 10
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
10 11
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
... ...
@@ -75,7 +76,7 @@ func (r *PolicyBindingRegistry) GetPolicyBinding(ctx kapi.Context, id string) (*
75 75
 		}
76 76
 	}
77 77
 
78
-	return nil, fmt.Errorf("PolicyBinding %v::%v not found", namespace, id)
78
+	return nil, kapierrors.NewNotFound("PolicyBinding", id)
79 79
 }
80 80
 
81 81
 // CreatePolicyBinding creates a new policyBinding.
... ...
@@ -108,7 +109,7 @@ func (r *PolicyBindingRegistry) UpdatePolicyBinding(ctx kapi.Context, policyBind
108 108
 		return errors.New("invalid request.  Namespace parameter required.")
109 109
 	}
110 110
 	if existing, _ := r.GetPolicyBinding(ctx, policyBinding.Name); existing == nil {
111
-		return fmt.Errorf("PolicyBinding %v::%v not found", namespace, policyBinding.Name)
111
+		return kapierrors.NewNotFound("PolicyBinding", policyBinding.Name)
112 112
 	}
113 113
 
114 114
 	addPolicyBinding(r.PolicyBindings, *policyBinding)
... ...
@@ -18,10 +18,13 @@ import (
18 18
 type DefaultRuleResolver struct {
19 19
 	policyGetter  PolicyGetter
20 20
 	bindingLister BindingLister
21
+
22
+	clusterPolicyGetter  PolicyGetter
23
+	clusterBindingLister BindingLister
21 24
 }
22 25
 
23
-func NewDefaultRuleResolver(policyGetter PolicyGetter, bindingLister BindingLister) *DefaultRuleResolver {
24
-	return &DefaultRuleResolver{policyGetter, bindingLister}
26
+func NewDefaultRuleResolver(policyGetter PolicyGetter, bindingLister BindingLister, clusterPolicyGetter PolicyGetter, clusterBindingLister BindingLister) *DefaultRuleResolver {
27
+	return &DefaultRuleResolver{policyGetter, bindingLister, clusterPolicyGetter, clusterBindingLister}
25 28
 }
26 29
 
27 30
 type AuthorizationRuleResolver interface {
... ...
@@ -44,16 +47,35 @@ type BindingLister interface {
44 44
 }
45 45
 
46 46
 func (a *DefaultRuleResolver) getPolicy(ctx kapi.Context) (*authorizationapi.Policy, error) {
47
-	policy, err := a.policyGetter.GetPolicy(ctx, authorizationapi.PolicyName)
47
+	namespace, _ := kapi.NamespaceFrom(ctx)
48
+
49
+	var policy *authorizationapi.Policy
50
+	var err error
51
+	switch {
52
+	case len(namespace) == 0:
53
+		policy, err = a.clusterPolicyGetter.GetPolicy(ctx, authorizationapi.PolicyName)
54
+	default:
55
+		policy, err = a.policyGetter.GetPolicy(ctx, authorizationapi.PolicyName)
56
+	}
57
+
48 58
 	if err != nil {
49 59
 		return nil, err
50 60
 	}
51
-
52 61
 	return policy, nil
53 62
 }
54 63
 
55 64
 func (a *DefaultRuleResolver) getPolicyBindings(ctx kapi.Context) ([]authorizationapi.PolicyBinding, error) {
56
-	policyBindingList, err := a.bindingLister.ListPolicyBindings(ctx, labels.Everything(), fields.Everything())
65
+	namespace, _ := kapi.NamespaceFrom(ctx)
66
+
67
+	var policyBindingList *authorizationapi.PolicyBindingList
68
+	var err error
69
+	switch {
70
+	case len(namespace) == 0:
71
+		policyBindingList, err = a.clusterBindingLister.ListPolicyBindings(ctx, labels.Everything(), fields.Everything())
72
+	default:
73
+		policyBindingList, err = a.bindingLister.ListPolicyBindings(ctx, labels.Everything(), fields.Everything())
74
+	}
75
+
57 76
 	if err != nil {
58 77
 		return nil, err
59 78
 	}
... ...
@@ -3,6 +3,7 @@ package client
3 3
 import (
4 4
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
5 5
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
6 7
 
7 8
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
8 9
 )
... ...
@@ -15,6 +16,7 @@ type ClusterPolicyInterface interface {
15 15
 	List(label labels.Selector, field fields.Selector) (*authorizationapi.ClusterPolicyList, error)
16 16
 	Get(name string) (*authorizationapi.ClusterPolicy, error)
17 17
 	Delete(name string) error
18
+	Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
18 19
 }
19 20
 
20 21
 type clusterPolicies struct {
... ...
@@ -46,3 +48,8 @@ func (c *clusterPolicies) Delete(name string) (err error) {
46 46
 	err = c.r.Delete().Resource("clusterPolicies").Name(name).Do().Error()
47 47
 	return
48 48
 }
49
+
50
+// Watch returns a watch.Interface that watches the requested policyBindings
51
+func (c *clusterPolicies) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
52
+	return c.r.Get().Prefix("watch").Resource("clusterPolicies").Param("resourceVersion", resourceVersion).LabelsSelectorParam(label).FieldsSelectorParam(field).Watch()
53
+}
... ...
@@ -3,6 +3,7 @@ package client
3 3
 import (
4 4
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
5 5
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
6 7
 
7 8
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
8 9
 )
... ...
@@ -16,6 +17,7 @@ type ClusterPolicyBindingInterface interface {
16 16
 	Get(name string) (*authorizationapi.ClusterPolicyBinding, error)
17 17
 	Create(policyBinding *authorizationapi.ClusterPolicyBinding) (*authorizationapi.ClusterPolicyBinding, error)
18 18
 	Delete(name string) error
19
+	Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
19 20
 }
20 21
 
21 22
 type clusterPolicyBindings struct {
... ...
@@ -55,3 +57,8 @@ func (c *clusterPolicyBindings) Delete(name string) (err error) {
55 55
 	err = c.r.Delete().Resource("clusterPolicyBindings").Name(name).Do().Error()
56 56
 	return
57 57
 }
58
+
59
+// Watch returns a watch.Interface that watches the requested policyBindings
60
+func (c *clusterPolicyBindings) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
61
+	return c.r.Get().Prefix("watch").Resource("clusterPolicyBindings").Param("resourceVersion", resourceVersion).LabelsSelectorParam(label).FieldsSelectorParam(field).Watch()
62
+}
... ...
@@ -14,6 +14,7 @@ type ClusterRoleBindingsInterface interface {
14 14
 type ClusterRoleBindingInterface interface {
15 15
 	List(label labels.Selector, field fields.Selector) (*authorizationapi.ClusterRoleBindingList, error)
16 16
 	Get(name string) (*authorizationapi.ClusterRoleBinding, error)
17
+	Update(roleBinding *authorizationapi.ClusterRoleBinding) (*authorizationapi.ClusterRoleBinding, error)
17 18
 	Create(roleBinding *authorizationapi.ClusterRoleBinding) (*authorizationapi.ClusterRoleBinding, error)
18 19
 	Delete(name string) error
19 20
 }
... ...
@@ -50,6 +51,13 @@ func (c *clusterRoleBindings) Create(roleBinding *authorizationapi.ClusterRoleBi
50 50
 	return
51 51
 }
52 52
 
53
+// Update updates the roleBinding on server. Returns the server's representation of the roleBinding and error if one occurs.
54
+func (c *clusterRoleBindings) Update(roleBinding *authorizationapi.ClusterRoleBinding) (result *authorizationapi.ClusterRoleBinding, err error) {
55
+	result = &authorizationapi.ClusterRoleBinding{}
56
+	err = c.r.Put().Resource("clusterRoleBindings").Name(roleBinding.Name).Body(roleBinding).Do().Into(result)
57
+	return
58
+}
59
+
53 60
 // Delete deletes a roleBinding, returns error if one occurs.
54 61
 func (c *clusterRoleBindings) Delete(name string) (err error) {
55 62
 	err = c.r.Delete().Resource("clusterRoleBindings").Name(name).Do().Error()
... ...
@@ -15,6 +15,7 @@ type ClusterRoleInterface interface {
15 15
 	List(label labels.Selector, field fields.Selector) (*authorizationapi.ClusterRoleList, error)
16 16
 	Get(name string) (*authorizationapi.ClusterRole, error)
17 17
 	Create(role *authorizationapi.ClusterRole) (*authorizationapi.ClusterRole, error)
18
+	Update(role *authorizationapi.ClusterRole) (*authorizationapi.ClusterRole, error)
18 19
 	Delete(name string) error
19 20
 }
20 21
 
... ...
@@ -50,6 +51,13 @@ func (c *clusterRoles) Create(role *authorizationapi.ClusterRole) (result *autho
50 50
 	return
51 51
 }
52 52
 
53
+// Update updates the roleBinding on server. Returns the server's representation of the roleBinding and error if one occurs.
54
+func (c *clusterRoles) Update(role *authorizationapi.ClusterRole) (result *authorizationapi.ClusterRole, err error) {
55
+	result = &authorizationapi.ClusterRole{}
56
+	err = c.r.Put().Resource("clusterRoles").Name(role.Name).Body(role).Do().Into(result)
57
+	return
58
+}
59
+
53 60
 // Delete deletes a role, returns error if one occurs.
54 61
 func (c *clusterRoles) Delete(name string) (err error) {
55 62
 	err = c.r.Delete().Resource("clusterRoles").Name(name).Do().Error()
... ...
@@ -3,6 +3,7 @@ package client
3 3
 import (
4 4
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
5 5
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
6 7
 
7 8
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
8 9
 )
... ...
@@ -25,3 +26,8 @@ func (c *FakeClusterPolicies) Delete(name string) error {
25 25
 	c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-clusterPolicy", Value: name})
26 26
 	return nil
27 27
 }
28
+
29
+func (c *FakeClusterPolicies) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
30
+	c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "watch-clusterPolicy"})
31
+	return nil, nil
32
+}
... ...
@@ -3,6 +3,7 @@ package client
3 3
 import (
4 4
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
5 5
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
6
+	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
6 7
 
7 8
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
8 9
 )
... ...
@@ -30,3 +31,8 @@ func (c *FakeClusterPolicyBindings) Delete(name string) error {
30 30
 	c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-clusterPolicyBinding", Value: name})
31 31
 	return nil
32 32
 }
33
+
34
+func (c *FakeClusterPolicyBindings) Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
35
+	c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "watch-clusterPolicyBinding"})
36
+	return nil, nil
37
+}
... ...
@@ -26,6 +26,11 @@ func (c *FakeClusterRoleBindings) Create(roleBinding *authorizationapi.ClusterRo
26 26
 	return obj.(*authorizationapi.ClusterRoleBinding), err
27 27
 }
28 28
 
29
+func (c *FakeClusterRoleBindings) Update(roleBinding *authorizationapi.ClusterRoleBinding) (*authorizationapi.ClusterRoleBinding, error) {
30
+	obj, err := c.Fake.Invokes(FakeAction{Action: "update-clusterRoleBinding"}, &authorizationapi.ClusterRoleBinding{})
31
+	return obj.(*authorizationapi.ClusterRoleBinding), err
32
+}
33
+
29 34
 func (c *FakeClusterRoleBindings) Delete(name string) error {
30 35
 	c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-clusterRoleBinding", Value: name})
31 36
 	return nil
... ...
@@ -26,6 +26,11 @@ func (c *FakeClusterRoles) Create(role *authorizationapi.ClusterRole) (*authoriz
26 26
 	return obj.(*authorizationapi.ClusterRole), err
27 27
 }
28 28
 
29
+func (c *FakeClusterRoles) Update(role *authorizationapi.ClusterRole) (*authorizationapi.ClusterRole, error) {
30
+	obj, err := c.Fake.Invokes(FakeAction{Action: "update-clusterRole"}, &authorizationapi.ClusterRole{})
31
+	return obj.(*authorizationapi.ClusterRole), err
32
+}
33
+
29 34
 func (c *FakeClusterRoles) Delete(name string) error {
30 35
 	c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-clusterRole", Value: name})
31 36
 	return nil
... ...
@@ -11,7 +11,6 @@ import (
11 11
 
12 12
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
13 13
 	"github.com/openshift/origin/pkg/client"
14
-	"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
15 14
 	"github.com/openshift/origin/pkg/cmd/util/clientcmd"
16 15
 )
17 16
 
... ...
@@ -50,7 +49,7 @@ func NewCmdAddRoleToGroup(name, fullName string, f *clientcmd.Factory, out io.Wr
50 50
 		},
51 51
 	}
52 52
 
53
-	cmd.Flags().StringVar(&options.RoleNamespace, "role-namespace", bootstrappolicy.DefaultMasterAuthorizationNamespace, "namespace where the role is located.")
53
+	cmd.Flags().StringVar(&options.RoleNamespace, "role-namespace", "", "namespace where the role is located.")
54 54
 
55 55
 	return cmd
56 56
 }
... ...
@@ -73,7 +72,7 @@ func NewCmdAddRoleToUser(name, fullName string, f *clientcmd.Factory, out io.Wri
73 73
 		},
74 74
 	}
75 75
 
76
-	cmd.Flags().StringVar(&options.RoleNamespace, "role-namespace", bootstrappolicy.DefaultMasterAuthorizationNamespace, "namespace where the role is located.")
76
+	cmd.Flags().StringVar(&options.RoleNamespace, "role-namespace", "", "namespace where the role is located.")
77 77
 
78 78
 	return cmd
79 79
 }
... ...
@@ -96,7 +95,7 @@ func NewCmdRemoveRoleFromGroup(name, fullName string, f *clientcmd.Factory, out
96 96
 		},
97 97
 	}
98 98
 
99
-	cmd.Flags().StringVar(&options.RoleNamespace, "role-namespace", bootstrappolicy.DefaultMasterAuthorizationNamespace, "namespace where the role is located.")
99
+	cmd.Flags().StringVar(&options.RoleNamespace, "role-namespace", "", "namespace where the role is located.")
100 100
 
101 101
 	return cmd
102 102
 }
... ...
@@ -119,7 +118,7 @@ func NewCmdRemoveRoleFromUser(name, fullName string, f *clientcmd.Factory, out i
119 119
 		},
120 120
 	}
121 121
 
122
-	cmd.Flags().StringVar(&options.RoleNamespace, "role-namespace", bootstrappolicy.DefaultMasterAuthorizationNamespace, "namespace where the role is located.")
122
+	cmd.Flags().StringVar(&options.RoleNamespace, "role-namespace", "", "namespace where the role is located.")
123 123
 
124 124
 	return cmd
125 125
 }
... ...
@@ -54,7 +54,6 @@ func NewCmdNewProject(name, fullName string, f *clientcmd.Factory, out io.Writer
54 54
 	}
55 55
 
56 56
 	// TODO remove once we have global policy objects
57
-	cmd.Flags().StringVar(&options.MasterPolicyNamespace, "master-policy-namespace", bootstrappolicy.DefaultMasterAuthorizationNamespace, "master policy namespace")
58 57
 	cmd.Flags().StringVar(&options.AdminRole, "admin-role", bootstrappolicy.AdminRoleName, "project admin role name in the master policy namespace")
59 58
 	cmd.Flags().StringVar(&options.AdminUser, "admin", "", "project admin username")
60 59
 	cmd.Flags().StringVar(&options.DisplayName, "display-name", "", "project display name")
... ...
@@ -839,7 +839,7 @@ func (d *ClusterPolicyDescriber) Describe(namespace, name string) (string, error
839 839
 		return "", err
840 840
 	}
841 841
 
842
-	return DescribePolicy(authorizationTypeConverter.ToPolicy(policy))
842
+	return DescribePolicy(authorizationapi.ToPolicy(policy))
843 843
 }
844 844
 
845 845
 type ClusterRoleDescriber struct {
... ...
@@ -854,7 +854,7 @@ func (d *ClusterRoleDescriber) Describe(namespace, name string) (string, error)
854 854
 		return "", err
855 855
 	}
856 856
 
857
-	return DescribeRole(authorizationTypeConverter.ToRole(role))
857
+	return DescribeRole(authorizationapi.ToRole(role))
858 858
 }
859 859
 
860 860
 // ClusterPolicyBindingDescriber generates information about a Project
... ...
@@ -870,7 +870,7 @@ func (d *ClusterPolicyBindingDescriber) Describe(namespace, name string) (string
870 870
 		return "", err
871 871
 	}
872 872
 
873
-	return DescribePolicyBinding(authorizationTypeConverter.ToPolicyBinding(policyBinding))
873
+	return DescribePolicyBinding(authorizationapi.ToPolicyBinding(policyBinding))
874 874
 }
875 875
 
876 876
 // ClusterRoleBindingDescriber generates information about a Project
... ...
@@ -887,5 +887,5 @@ func (d *ClusterRoleBindingDescriber) Describe(namespace, name string) (string,
887 887
 	}
888 888
 
889 889
 	role, err := d.ClusterRoles().Get(roleBinding.RoleRef.Name)
890
-	return DescribeRoleBinding(authorizationTypeConverter.ToRoleBinding(roleBinding), authorizationTypeConverter.ToRole(role), err)
890
+	return DescribeRoleBinding(authorizationapi.ToRoleBinding(roleBinding), authorizationapi.ToRole(role), err)
891 891
 }
... ...
@@ -52,10 +52,6 @@ var (
52 52
 	IsPersonalSubjectAccessReviewColumns = []string{"NAME"}
53 53
 )
54 54
 
55
-var (
56
-	authorizationTypeConverter = authorizationapi.TypeConverter{""}
57
-)
58
-
59 55
 // NewHumanReadablePrinter returns a new HumanReadablePrinter
60 56
 func NewHumanReadablePrinter(noHeaders bool) *kctl.HumanReadablePrinter {
61 57
 	p := kctl.NewHumanReadablePrinter(noHeaders)
... ...
@@ -409,35 +405,35 @@ func printPolicyBindingList(list *authorizationapi.PolicyBindingList, w io.Write
409 409
 }
410 410
 
411 411
 func printClusterPolicy(policy *authorizationapi.ClusterPolicy, w io.Writer) error {
412
-	return printPolicy(authorizationTypeConverter.ToPolicy(policy), w)
412
+	return printPolicy(authorizationapi.ToPolicy(policy), w)
413 413
 }
414 414
 
415 415
 func printClusterPolicyList(list *authorizationapi.ClusterPolicyList, w io.Writer) error {
416
-	return printPolicyList(authorizationTypeConverter.ToPolicyList(list), w)
416
+	return printPolicyList(authorizationapi.ToPolicyList(list), w)
417 417
 }
418 418
 
419 419
 func printClusterPolicyBinding(policyBinding *authorizationapi.ClusterPolicyBinding, w io.Writer) error {
420
-	return printPolicyBinding(authorizationTypeConverter.ToPolicyBinding(policyBinding), w)
420
+	return printPolicyBinding(authorizationapi.ToPolicyBinding(policyBinding), w)
421 421
 }
422 422
 
423 423
 func printClusterPolicyBindingList(list *authorizationapi.ClusterPolicyBindingList, w io.Writer) error {
424
-	return printPolicyBindingList(authorizationTypeConverter.ToPolicyBindingList(list), w)
424
+	return printPolicyBindingList(authorizationapi.ToPolicyBindingList(list), w)
425 425
 }
426 426
 
427 427
 func printClusterRole(role *authorizationapi.ClusterRole, w io.Writer) error {
428
-	return printRole(authorizationTypeConverter.ToRole(role), w)
428
+	return printRole(authorizationapi.ToRole(role), w)
429 429
 }
430 430
 
431 431
 func printClusterRoleList(list *authorizationapi.ClusterRoleList, w io.Writer) error {
432
-	return printRoleList(authorizationTypeConverter.ToRoleList(list), w)
432
+	return printRoleList(authorizationapi.ToRoleList(list), w)
433 433
 }
434 434
 
435 435
 func printClusterRoleBinding(roleBinding *authorizationapi.ClusterRoleBinding, w io.Writer) error {
436
-	return printRoleBinding(authorizationTypeConverter.ToRoleBinding(roleBinding), w)
436
+	return printRoleBinding(authorizationapi.ToRoleBinding(roleBinding), w)
437 437
 }
438 438
 
439 439
 func printClusterRoleBindingList(list *authorizationapi.ClusterRoleBindingList, w io.Writer) error {
440
-	return printRoleBindingList(authorizationTypeConverter.ToRoleBindingList(list), w)
440
+	return printRoleBindingList(authorizationapi.ToRoleBindingList(list), w)
441 441
 }
442 442
 
443 443
 func printIsPersonalSubjectAccessReview(a *authorizationapi.IsPersonalSubjectAccessReview, w io.Writer) error {
... ...
@@ -28,7 +28,6 @@ const (
28 28
 type CreateBootstrapPolicyFileOptions struct {
29 29
 	File string
30 30
 
31
-	MasterAuthorizationNamespace      string
32 31
 	OpenShiftSharedResourcesNamespace string
33 32
 }
34 33
 
... ...
@@ -54,7 +53,6 @@ func NewCommandCreateBootstrapPolicyFile(commandName string, fullName string, ou
54 54
 
55 55
 	flags.StringVar(&options.File, "filename", DefaultPolicyFile, "The policy template file that will be written with roles and bindings.")
56 56
 
57
-	flags.StringVar(&options.MasterAuthorizationNamespace, "master-namespace", bootstrappolicy.DefaultMasterAuthorizationNamespace, "Global authorization namespace.")
58 57
 	flags.StringVar(&options.OpenShiftSharedResourcesNamespace, "openshift-namespace", "openshift", "Namespace for shared openshift resources.")
59 58
 
60 59
 	return cmd
... ...
@@ -67,9 +65,6 @@ func (o CreateBootstrapPolicyFileOptions) Validate(args []string) error {
67 67
 	if len(o.File) == 0 {
68 68
 		return errors.New("filename must be provided")
69 69
 	}
70
-	if len(o.MasterAuthorizationNamespace) == 0 {
71
-		return errors.New("master-namespace must be provided")
72
-	}
73 70
 	if len(o.OpenShiftSharedResourcesNamespace) == 0 {
74 71
 		return errors.New("openshift-namespace must be provided")
75 72
 	}
... ...
@@ -84,14 +79,24 @@ func (o CreateBootstrapPolicyFileOptions) CreateBootstrapPolicyFile() error {
84 84
 
85 85
 	policyTemplate := &api.Template{}
86 86
 
87
-	roles := bootstrappolicy.GetBootstrapRoles(o.MasterAuthorizationNamespace, o.OpenShiftSharedResourcesNamespace)
88
-	for i := range roles {
89
-		policyTemplate.Objects = append(policyTemplate.Objects, &roles[i])
87
+	clusterRoles := bootstrappolicy.GetBootstrapClusterRoles()
88
+	for i := range clusterRoles {
89
+		policyTemplate.Objects = append(policyTemplate.Objects, &clusterRoles[i])
90
+	}
91
+
92
+	clusterRoleBindings := bootstrappolicy.GetBootstrapClusterRoleBindings()
93
+	for i := range clusterRoleBindings {
94
+		policyTemplate.Objects = append(policyTemplate.Objects, &clusterRoleBindings[i])
95
+	}
96
+
97
+	openshiftRoles := bootstrappolicy.GetBootstrapOpenshiftRoles(o.OpenShiftSharedResourcesNamespace)
98
+	for i := range openshiftRoles {
99
+		policyTemplate.Objects = append(policyTemplate.Objects, &openshiftRoles[i])
90 100
 	}
91 101
 
92
-	roleBindings := bootstrappolicy.GetBootstrapRoleBindings(o.MasterAuthorizationNamespace, o.OpenShiftSharedResourcesNamespace)
93
-	for i := range roleBindings {
94
-		policyTemplate.Objects = append(policyTemplate.Objects, &roleBindings[i])
102
+	openshiftRoleBindings := bootstrappolicy.GetBootstrapOpenshiftRoleBindings(o.OpenShiftSharedResourcesNamespace)
103
+	for i := range openshiftRoleBindings {
104
+		policyTemplate.Objects = append(policyTemplate.Objects, &openshiftRoleBindings[i])
95 105
 	}
96 106
 
97 107
 	versionedPolicyTemplate, err := kapi.Scheme.ConvertToVersion(policyTemplate, latest.Version)
... ...
@@ -14,7 +14,6 @@ import (
14 14
 	kcmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
15 15
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
16 16
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
17
-	utilerrors "github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors"
18 17
 
19 18
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
20 19
 	"github.com/openshift/origin/pkg/api/latest"
... ...
@@ -26,9 +25,17 @@ import (
26 26
 	roleregistry "github.com/openshift/origin/pkg/authorization/registry/role"
27 27
 	rolestorage "github.com/openshift/origin/pkg/authorization/registry/role/policybased"
28 28
 	rolebindingstorage "github.com/openshift/origin/pkg/authorization/registry/rolebinding/policybased"
29
+
30
+	clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
31
+	clusterpolicyetcd "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy/etcd"
32
+	clusterpolicybindingregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding"
33
+	clusterpolicybindingetcd "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding/etcd"
34
+	clusterroleregistry "github.com/openshift/origin/pkg/authorization/registry/clusterrole"
35
+	clusterrolestorage "github.com/openshift/origin/pkg/authorization/registry/clusterrole/proxy"
36
+	clusterrolebindingstorage "github.com/openshift/origin/pkg/authorization/registry/clusterrolebinding/proxy"
37
+
29 38
 	"github.com/openshift/origin/pkg/cmd/cli/describe"
30 39
 	configapilatest "github.com/openshift/origin/pkg/cmd/server/api/latest"
31
-	configvalidation "github.com/openshift/origin/pkg/cmd/server/api/validation"
32 40
 	"github.com/openshift/origin/pkg/cmd/server/etcd"
33 41
 	cmdclientcmd "github.com/openshift/origin/pkg/cmd/util/clientcmd"
34 42
 	templateapi "github.com/openshift/origin/pkg/template/api"
... ...
@@ -92,9 +99,6 @@ func (o OverwriteBootstrapPolicyOptions) OverwriteBootstrapPolicy() error {
92 92
 	if err != nil {
93 93
 		return err
94 94
 	}
95
-	if err := configvalidation.ValidateNamespace(masterConfig.PolicyConfig.MasterAuthorizationNamespace, "masterAuthorizationNamespace"); len(err) > 0 {
96
-		return utilerrors.NewAggregate(err)
97
-	}
98 95
 
99 96
 	// Connect and setup etcd interfaces
100 97
 	etcdClient, err := etcd.GetAndTestEtcdClient(masterConfig.EtcdClientInfo)
... ...
@@ -106,10 +110,10 @@ func (o OverwriteBootstrapPolicyOptions) OverwriteBootstrapPolicy() error {
106 106
 		return err
107 107
 	}
108 108
 
109
-	return OverwriteBootstrapPolicy(etcdHelper, masterConfig.PolicyConfig.MasterAuthorizationNamespace, o.File, o.CreateBootstrapPolicyCommand, o.Force, o.Out)
109
+	return OverwriteBootstrapPolicy(etcdHelper, o.File, o.CreateBootstrapPolicyCommand, o.Force, o.Out)
110 110
 }
111 111
 
112
-func OverwriteBootstrapPolicy(etcdHelper tools.EtcdHelper, masterNamespace, policyFile, createBootstrapPolicyCommand string, change bool, out io.Writer) error {
112
+func OverwriteBootstrapPolicy(etcdHelper tools.EtcdHelper, policyFile, createBootstrapPolicyCommand string, change bool, out io.Writer) error {
113 113
 	if !change {
114 114
 		fmt.Fprintf(out, "Performing a dry run of policy overwrite:\n\n")
115 115
 	}
... ...
@@ -131,8 +135,15 @@ func OverwriteBootstrapPolicy(etcdHelper tools.EtcdHelper, masterNamespace, poli
131 131
 
132 132
 	policyRegistry := policyregistry.NewRegistry(policyetcd.NewStorage(etcdHelper))
133 133
 	policyBindingRegistry := policybindingregistry.NewRegistry(policybindingetcd.NewStorage(etcdHelper))
134
+
135
+	clusterPolicyRegistry := clusterpolicyregistry.NewRegistry(clusterpolicyetcd.NewStorage(etcdHelper))
136
+	clusterPolicyBindingRegistry := clusterpolicybindingregistry.NewRegistry(clusterpolicybindingetcd.NewStorage(etcdHelper))
137
+
134 138
 	roleRegistry := roleregistry.NewRegistry(rolestorage.NewVirtualStorage(policyRegistry))
135
-	roleBindingStorage := rolebindingstorage.NewVirtualStorage(policyRegistry, policyBindingRegistry, masterNamespace)
139
+	roleBindingStorage := rolebindingstorage.NewVirtualStorage(policyRegistry, policyBindingRegistry, clusterPolicyRegistry, clusterPolicyBindingRegistry)
140
+	clusterRoleStorage := clusterrolestorage.NewClusterRoleStorage(clusterPolicyRegistry)
141
+	clusterRoleRegistry := clusterroleregistry.NewRegistry(clusterRoleStorage)
142
+	clusterRoleBindingStorage := clusterrolebindingstorage.NewClusterRoleBindingStorage(clusterPolicyRegistry, clusterPolicyBindingRegistry)
136 143
 
137 144
 	return r.Visit(func(info *resource.Info) error {
138 145
 		template, ok := info.Object.(*templateapi.Template)
... ...
@@ -170,6 +181,33 @@ func OverwriteBootstrapPolicy(etcdHelper tools.EtcdHelper, masterNamespace, poli
170 170
 					}
171 171
 				}
172 172
 
173
+			case *authorizationapi.ClusterRole:
174
+				ctx := kapi.WithNamespace(kapi.NewContext(), t.Namespace)
175
+				if change {
176
+					clusterRoleRegistry.DeleteClusterRole(ctx, t.Name)
177
+					if _, err := clusterRoleRegistry.CreateClusterRole(ctx, t); err != nil {
178
+						return err
179
+					}
180
+				} else {
181
+					fmt.Fprintf(out, "Overwrite role %s/%s\n", t.Namespace, t.Name)
182
+					if s, err := describe.DescribeRole(authorizationapi.ToRole(t)); err == nil {
183
+						fmt.Fprintf(out, "%s\n", s)
184
+					}
185
+				}
186
+			case *authorizationapi.ClusterRoleBinding:
187
+				ctx := kapi.WithNamespace(kapi.NewContext(), t.Namespace)
188
+				if change {
189
+					clusterRoleBindingStorage.Delete(ctx, t.Name, nil)
190
+					if _, err := clusterRoleBindingStorage.CreateClusterRoleBindingWithEscalation(ctx, t); err != nil {
191
+						return err
192
+					}
193
+				} else {
194
+					fmt.Fprintf(out, "Overwrite role binding %s/%s\n", t.Namespace, t.Name)
195
+					if s, err := describe.DescribeRoleBinding(authorizationapi.ToRoleBinding(t), nil, nil); err == nil {
196
+						fmt.Fprintf(out, "%s\n", s)
197
+					}
198
+				}
199
+
173 200
 			default:
174 201
 				return errors.New("only roles and rolebindings may be created in this mode")
175 202
 			}
... ...
@@ -103,8 +103,6 @@ type PolicyConfig struct {
103 103
 	// BootstrapPolicyFile points to a template that contains roles and rolebindings that will be created if no policy object exists in the master namespace
104 104
 	BootstrapPolicyFile string
105 105
 
106
-	// MasterAuthorizationNamespace is the global namespace for Policy
107
-	MasterAuthorizationNamespace string
108 106
 	// OpenShiftSharedResourcesNamespace is the namespace where shared OpenShift resources live (like shared templates)
109 107
 	OpenShiftSharedResourcesNamespace string
110 108
 }
... ...
@@ -98,8 +98,6 @@ type PolicyConfig struct {
98 98
 	// BootstrapPolicyFile points to a template that contains roles and rolebindings that will be created if no policy object exists in the master namespace
99 99
 	BootstrapPolicyFile string `json:"bootstrapPolicyFile"`
100 100
 
101
-	// MasterAuthorizationNamespace is the global namespace for Policy
102
-	MasterAuthorizationNamespace string `json:"masterAuthorizationNamespace"`
103 101
 	// OpenShiftSharedResourcesNamespace is the namespace where shared OpenShift resources live (like shared templates)
104 102
 	OpenShiftSharedResourcesNamespace string `json:"openshiftSharedResourcesNamespace"`
105 103
 }
... ...
@@ -191,7 +191,6 @@ func ValidatePolicyConfig(config api.PolicyConfig) fielderrors.ValidationErrorLi
191 191
 	allErrs := fielderrors.ValidationErrorList{}
192 192
 
193 193
 	allErrs = append(allErrs, ValidateFile(config.BootstrapPolicyFile, "bootstrapPolicyFile")...)
194
-	allErrs = append(allErrs, ValidateNamespace(config.MasterAuthorizationNamespace, "masterAuthorizationNamespace")...)
195 194
 	allErrs = append(allErrs, ValidateNamespace(config.OpenShiftSharedResourcesNamespace, "openShiftSharedResourcesNamespace")...)
196 195
 
197 196
 	return allErrs
... ...
@@ -2,7 +2,6 @@ package bootstrappolicy
2 2
 
3 3
 // known namespaces
4 4
 const (
5
-	DefaultMasterAuthorizationNamespace      = "master"
6 5
 	DefaultOpenShiftSharedResourcesNamespace = "openshift"
7 6
 )
8 7
 
... ...
@@ -8,15 +8,6 @@ import (
8 8
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
9 9
 )
10 10
 
11
-func GetBootstrapRoles(masterNamespace, openshiftNamespace string) []authorizationapi.Role {
12
-	masterRoles := GetBootstrapMasterRoles(masterNamespace)
13
-	openshiftRoles := GetBootstrapOpenshiftRoles(openshiftNamespace)
14
-	ret := make([]authorizationapi.Role, 0, len(masterRoles)+len(openshiftRoles))
15
-	ret = append(ret, masterRoles...)
16
-	ret = append(ret, openshiftRoles...)
17
-	return ret
18
-}
19
-
20 11
 func GetBootstrapOpenshiftRoles(openshiftNamespace string) []authorizationapi.Role {
21 12
 	return []authorizationapi.Role{
22 13
 		{
... ...
@@ -33,12 +24,11 @@ func GetBootstrapOpenshiftRoles(openshiftNamespace string) []authorizationapi.Ro
33 33
 		},
34 34
 	}
35 35
 }
36
-func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
37
-	return []authorizationapi.Role{
36
+func GetBootstrapClusterRoles() []authorizationapi.ClusterRole {
37
+	return []authorizationapi.ClusterRole{
38 38
 		{
39 39
 			ObjectMeta: kapi.ObjectMeta{
40
-				Name:      ClusterAdminRoleName,
41
-				Namespace: masterNamespace,
40
+				Name: ClusterAdminRoleName,
42 41
 			},
43 42
 			Rules: []authorizationapi.PolicyRule{
44 43
 				{
... ...
@@ -53,8 +43,7 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
53 53
 		},
54 54
 		{
55 55
 			ObjectMeta: kapi.ObjectMeta{
56
-				Name:      AdminRoleName,
57
-				Namespace: masterNamespace,
56
+				Name: AdminRoleName,
58 57
 			},
59 58
 			Rules: []authorizationapi.PolicyRule{
60 59
 				{
... ...
@@ -69,8 +58,7 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
69 69
 		},
70 70
 		{
71 71
 			ObjectMeta: kapi.ObjectMeta{
72
-				Name:      EditRoleName,
73
-				Namespace: masterNamespace,
72
+				Name: EditRoleName,
74 73
 			},
75 74
 			Rules: []authorizationapi.PolicyRule{
76 75
 				{
... ...
@@ -85,8 +73,7 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
85 85
 		},
86 86
 		{
87 87
 			ObjectMeta: kapi.ObjectMeta{
88
-				Name:      ViewRoleName,
89
-				Namespace: masterNamespace,
88
+				Name: ViewRoleName,
90 89
 			},
91 90
 			Rules: []authorizationapi.PolicyRule{
92 91
 				{
... ...
@@ -97,8 +84,7 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
97 97
 		},
98 98
 		{
99 99
 			ObjectMeta: kapi.ObjectMeta{
100
-				Name:      BasicUserRoleName,
101
-				Namespace: masterNamespace,
100
+				Name: BasicUserRoleName,
102 101
 			},
103 102
 			Rules: []authorizationapi.PolicyRule{
104 103
 				{Verbs: util.NewStringSet("get"), Resources: util.NewStringSet("users"), ResourceNames: util.NewStringSet("~")},
... ...
@@ -109,8 +95,7 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
109 109
 		},
110 110
 		{
111 111
 			ObjectMeta: kapi.ObjectMeta{
112
-				Name:      SelfProvisionerRoleName,
113
-				Namespace: masterNamespace,
112
+				Name: SelfProvisionerRoleName,
114 113
 			},
115 114
 			Rules: []authorizationapi.PolicyRule{
116 115
 				{Verbs: util.NewStringSet("create"), Resources: util.NewStringSet("projectrequests")},
... ...
@@ -118,8 +103,7 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
118 118
 		},
119 119
 		{
120 120
 			ObjectMeta: kapi.ObjectMeta{
121
-				Name:      StatusCheckerRoleName,
122
-				Namespace: masterNamespace,
121
+				Name: StatusCheckerRoleName,
123 122
 			},
124 123
 			Rules: []authorizationapi.PolicyRule{
125 124
 				{
... ...
@@ -130,8 +114,7 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
130 130
 		},
131 131
 		{
132 132
 			ObjectMeta: kapi.ObjectMeta{
133
-				Name:      DeployerRoleName,
134
-				Namespace: masterNamespace,
133
+				Name: DeployerRoleName,
135 134
 			},
136 135
 			Rules: []authorizationapi.PolicyRule{
137 136
 				{
... ...
@@ -142,8 +125,7 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
142 142
 		},
143 143
 		{
144 144
 			ObjectMeta: kapi.ObjectMeta{
145
-				Name:      InternalComponentRoleName,
146
-				Namespace: masterNamespace,
145
+				Name: InternalComponentRoleName,
147 146
 			},
148 147
 			Rules: []authorizationapi.PolicyRule{
149 148
 				{
... ...
@@ -154,8 +136,7 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
154 154
 		},
155 155
 		{
156 156
 			ObjectMeta: kapi.ObjectMeta{
157
-				Name:      DeleteTokensRoleName,
158
-				Namespace: masterNamespace,
157
+				Name: DeleteTokensRoleName,
159 158
 			},
160 159
 			Rules: []authorizationapi.PolicyRule{
161 160
 				{
... ...
@@ -166,8 +147,7 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
166 166
 		},
167 167
 		{
168 168
 			ObjectMeta: kapi.ObjectMeta{
169
-				Name:      RouterRoleName,
170
-				Namespace: masterNamespace,
169
+				Name: RouterRoleName,
171 170
 			},
172 171
 			Rules: []authorizationapi.PolicyRule{
173 172
 				{
... ...
@@ -178,8 +158,7 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
178 178
 		},
179 179
 		{
180 180
 			ObjectMeta: kapi.ObjectMeta{
181
-				Name:      RegistryRoleName,
182
-				Namespace: masterNamespace,
181
+				Name: RegistryRoleName,
183 182
 			},
184 183
 			Rules: []authorizationapi.PolicyRule{
185 184
 				{
... ...
@@ -204,15 +183,6 @@ func GetBootstrapMasterRoles(masterNamespace string) []authorizationapi.Role {
204 204
 	}
205 205
 }
206 206
 
207
-func GetBootstrapRoleBindings(masterNamespace, openshiftNamespace string) []authorizationapi.RoleBinding {
208
-	masterRoleBindings := GetBootstrapMasterRoleBindings(masterNamespace)
209
-	openshiftRoleBindings := GetBootstrapOpenshiftRoleBindings(openshiftNamespace)
210
-	ret := make([]authorizationapi.RoleBinding, 0, len(masterRoleBindings)+len(openshiftRoleBindings))
211
-	ret = append(ret, masterRoleBindings...)
212
-	ret = append(ret, openshiftRoleBindings...)
213
-	return ret
214
-}
215
-
216 207
 func GetBootstrapOpenshiftRoleBindings(openshiftNamespace string) []authorizationapi.RoleBinding {
217 208
 	return []authorizationapi.RoleBinding{
218 209
 		{
... ...
@@ -228,105 +198,88 @@ func GetBootstrapOpenshiftRoleBindings(openshiftNamespace string) []authorizatio
228 228
 		},
229 229
 	}
230 230
 }
231
-func GetBootstrapMasterRoleBindings(masterNamespace string) []authorizationapi.RoleBinding {
232
-	return []authorizationapi.RoleBinding{
231
+
232
+func GetBootstrapClusterRoleBindings() []authorizationapi.ClusterRoleBinding {
233
+	return []authorizationapi.ClusterRoleBinding{
233 234
 		{
234 235
 			ObjectMeta: kapi.ObjectMeta{
235
-				Name:      InternalComponentRoleBindingName,
236
-				Namespace: masterNamespace,
236
+				Name: InternalComponentRoleBindingName,
237 237
 			},
238 238
 			RoleRef: kapi.ObjectReference{
239
-				Name:      InternalComponentRoleName,
240
-				Namespace: masterNamespace,
239
+				Name: InternalComponentRoleName,
241 240
 			},
242 241
 			Users:  util.NewStringSet(InternalComponentUsername, InternalComponentKubeUsername),
243 242
 			Groups: util.NewStringSet(NodesGroup),
244 243
 		},
245 244
 		{
246 245
 			ObjectMeta: kapi.ObjectMeta{
247
-				Name:      DeployerRoleBindingName,
248
-				Namespace: masterNamespace,
246
+				Name: DeployerRoleBindingName,
249 247
 			},
250 248
 			RoleRef: kapi.ObjectReference{
251
-				Name:      DeployerRoleName,
252
-				Namespace: masterNamespace,
249
+				Name: DeployerRoleName,
253 250
 			},
254 251
 			Users: util.NewStringSet(DeployerUsername),
255 252
 		},
256 253
 		{
257 254
 			ObjectMeta: kapi.ObjectMeta{
258
-				Name:      ClusterAdminRoleBindingName,
259
-				Namespace: masterNamespace,
255
+				Name: ClusterAdminRoleBindingName,
260 256
 			},
261 257
 			RoleRef: kapi.ObjectReference{
262
-				Name:      ClusterAdminRoleName,
263
-				Namespace: masterNamespace,
258
+				Name: ClusterAdminRoleName,
264 259
 			},
265 260
 			Groups: util.NewStringSet(ClusterAdminGroup),
266 261
 		},
267 262
 		{
268 263
 			ObjectMeta: kapi.ObjectMeta{
269
-				Name:      BasicUserRoleBindingName,
270
-				Namespace: masterNamespace,
264
+				Name: BasicUserRoleBindingName,
271 265
 			},
272 266
 			RoleRef: kapi.ObjectReference{
273
-				Name:      BasicUserRoleName,
274
-				Namespace: masterNamespace,
267
+				Name: BasicUserRoleName,
275 268
 			},
276 269
 			Groups: util.NewStringSet(AuthenticatedGroup),
277 270
 		},
278 271
 		{
279 272
 			ObjectMeta: kapi.ObjectMeta{
280
-				Name:      SelfProvisionerRoleBindingName,
281
-				Namespace: masterNamespace,
273
+				Name: SelfProvisionerRoleBindingName,
282 274
 			},
283 275
 			RoleRef: kapi.ObjectReference{
284
-				Name:      SelfProvisionerRoleName,
285
-				Namespace: masterNamespace,
276
+				Name: SelfProvisionerRoleName,
286 277
 			},
287 278
 			Groups: util.NewStringSet(AuthenticatedGroup),
288 279
 		},
289 280
 		{
290 281
 			ObjectMeta: kapi.ObjectMeta{
291
-				Name:      DeleteTokensRoleBindingName,
292
-				Namespace: masterNamespace,
282
+				Name: DeleteTokensRoleBindingName,
293 283
 			},
294 284
 			RoleRef: kapi.ObjectReference{
295
-				Name:      DeleteTokensRoleName,
296
-				Namespace: masterNamespace,
285
+				Name: DeleteTokensRoleName,
297 286
 			},
298 287
 			Groups: util.NewStringSet(AuthenticatedGroup, UnauthenticatedGroup),
299 288
 		},
300 289
 		{
301 290
 			ObjectMeta: kapi.ObjectMeta{
302
-				Name:      StatusCheckerRoleBindingName,
303
-				Namespace: masterNamespace,
291
+				Name: StatusCheckerRoleBindingName,
304 292
 			},
305 293
 			RoleRef: kapi.ObjectReference{
306
-				Name:      StatusCheckerRoleName,
307
-				Namespace: masterNamespace,
294
+				Name: StatusCheckerRoleName,
308 295
 			},
309 296
 			Groups: util.NewStringSet(AuthenticatedGroup, UnauthenticatedGroup),
310 297
 		},
311 298
 		{
312 299
 			ObjectMeta: kapi.ObjectMeta{
313
-				Name:      RouterRoleBindingName,
314
-				Namespace: masterNamespace,
300
+				Name: RouterRoleBindingName,
315 301
 			},
316 302
 			RoleRef: kapi.ObjectReference{
317
-				Name:      RouterRoleName,
318
-				Namespace: masterNamespace,
303
+				Name: RouterRoleName,
319 304
 			},
320 305
 			Groups: util.NewStringSet(RouterGroup),
321 306
 		},
322 307
 		{
323 308
 			ObjectMeta: kapi.ObjectMeta{
324
-				Name:      RegistryRoleBindingName,
325
-				Namespace: masterNamespace,
309
+				Name: RegistryRoleBindingName,
326 310
 			},
327 311
 			RoleRef: kapi.ObjectReference{
328
-				Name:      RegistryRoleName,
329
-				Namespace: masterNamespace,
312
+				Name: RegistryRoleName,
330 313
 			},
331 314
 			Groups: util.NewStringSet(RegistryGroup),
332 315
 		},
... ...
@@ -90,8 +90,10 @@ import (
90 90
 	"github.com/openshift/origin/pkg/user/registry/useridentitymapping"
91 91
 
92 92
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
93
-	clusterpolicystorage "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy/proxy"
94
-	clusterpolicybindingstorage "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding/proxy"
93
+	clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
94
+	clusterpolicystorage "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy/etcd"
95
+	clusterpolicybindingregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding"
96
+	clusterpolicybindingstorage "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding/etcd"
95 97
 	clusterrolestorage "github.com/openshift/origin/pkg/authorization/registry/clusterrole/proxy"
96 98
 	clusterrolebindingstorage "github.com/openshift/origin/pkg/authorization/registry/clusterrolebinding/proxy"
97 99
 	policyregistry "github.com/openshift/origin/pkg/authorization/registry/policy"
... ...
@@ -161,8 +163,17 @@ func (c *MasterConfig) InstallProtectedAPI(container *restful.Container) []strin
161 161
 	policyRegistry := policyregistry.NewRegistry(policyStorage)
162 162
 	policyBindingStorage := policybindingetcd.NewStorage(c.EtcdHelper)
163 163
 	policyBindingRegistry := policybindingregistry.NewRegistry(policyBindingStorage)
164
+
165
+	clusterPolicyStorage := clusterpolicystorage.NewStorage(c.EtcdHelper)
166
+	clusterPolicyRegistry := clusterpolicyregistry.NewRegistry(clusterPolicyStorage)
167
+	clusterPolicyBindingStorage := clusterpolicybindingstorage.NewStorage(c.EtcdHelper)
168
+	clusterPolicyBindingRegistry := clusterpolicybindingregistry.NewRegistry(clusterPolicyBindingStorage)
169
+
164 170
 	roleStorage := rolestorage.NewVirtualStorage(policyRegistry)
165
-	roleBindingStorage := rolebindingstorage.NewVirtualStorage(policyRegistry, policyBindingRegistry, c.Options.PolicyConfig.MasterAuthorizationNamespace)
171
+	roleBindingStorage := rolebindingstorage.NewVirtualStorage(policyRegistry, policyBindingRegistry, clusterPolicyRegistry, clusterPolicyBindingRegistry)
172
+	clusterRoleStorage := clusterrolestorage.NewClusterRoleStorage(clusterPolicyRegistry)
173
+	clusterRoleBindingStorage := clusterrolebindingstorage.NewClusterRoleBindingStorage(clusterPolicyRegistry, clusterPolicyBindingRegistry)
174
+
166 175
 	subjectAccessReviewStorage := subjectaccessreview.NewREST(c.Authorizer)
167 176
 	subjectAccessReviewRegistry := subjectaccessreview.NewRegistry(subjectAccessReviewStorage)
168 177
 
... ...
@@ -219,7 +230,7 @@ func (c *MasterConfig) InstallProtectedAPI(container *restful.Container) []strin
219 219
 		glog.Errorf("Error parsing project request template value: %v", err)
220 220
 		// we can continue on, the storage that gets created will be valid, it simply won't work properly.  There's no reason to kill the master
221 221
 	}
222
-	projectRequestStorage := projectrequeststorage.NewREST(c.Options.ProjectRequestConfig.ProjectRequestMessage, namespace, templateName, roleBindingStorage, *projectStorage, c.PrivilegedLoopbackOpenShiftClient)
222
+	projectRequestStorage := projectrequeststorage.NewREST(c.Options.ProjectRequestConfig.ProjectRequestMessage, namespace, templateName, c.PrivilegedLoopbackOpenShiftClient)
223 223
 
224 224
 	// initialize OpenShift API
225 225
 	storage := map[string]rest.Storage{
... ...
@@ -273,10 +284,10 @@ func (c *MasterConfig) InstallProtectedAPI(container *restful.Container) []strin
273 273
 		"roles":          roleStorage,
274 274
 		"roleBindings":   roleBindingStorage,
275 275
 
276
-		"clusterPolicies":       clusterpolicystorage.NewClusterPolicyStorage(c.Options.PolicyConfig.MasterAuthorizationNamespace, policyStorage),
277
-		"clusterPolicyBindings": clusterpolicybindingstorage.NewClusterPolicyBindingStorage(c.Options.PolicyConfig.MasterAuthorizationNamespace, policyBindingStorage),
278
-		"clusterRoleBindings":   clusterrolebindingstorage.NewClusterRoleBindingStorage(c.Options.PolicyConfig.MasterAuthorizationNamespace, roleBindingStorage),
279
-		"clusterRoles":          clusterrolestorage.NewClusterRoleStorage(c.Options.PolicyConfig.MasterAuthorizationNamespace, roleStorage),
276
+		"clusterPolicies":       clusterPolicyStorage,
277
+		"clusterPolicyBindings": clusterPolicyBindingStorage,
278
+		"clusterRoleBindings":   clusterRoleBindingStorage,
279
+		"clusterRoles":          clusterRoleStorage,
280 280
 	}
281 281
 
282 282
 	// for v1beta1, we dual register camelCase and camelcase names
... ...
@@ -537,10 +548,8 @@ func (c *MasterConfig) Run(protected []APIInstaller, unprotected []APIInstaller)
537 537
 
538 538
 	// Attempt to create the required policy rules now, and then stick in a forever loop to make sure they are always available
539 539
 	c.ensureComponentAuthorizationRules()
540
-	c.ensureMasterAuthorizationNamespace()
541 540
 	c.ensureOpenShiftSharedResourcesNamespace()
542 541
 	go util.Forever(func() {
543
-		c.ensureMasterAuthorizationNamespace()
544 542
 		c.ensureOpenShiftSharedResourcesNamespace()
545 543
 	}, 10*time.Second)
546 544
 
... ...
@@ -582,33 +591,13 @@ func (c *MasterConfig) checkProjectRequestTemplate() {
582 582
 		return
583 583
 	}
584 584
 
585
-	template := projectrequeststorage.NewSampleTemplate(c.Options.PolicyConfig.MasterAuthorizationNamespace, namespace, templateName)
585
+	template := projectrequeststorage.NewSampleTemplate(namespace, templateName)
586 586
 	if _, err := c.PrivilegedLoopbackOpenShiftClient.Templates(namespace).Create(template); err != nil {
587 587
 		glog.Errorf(baseErrorFormat+"  Caused by: %v", c.Options.ProjectRequestConfig.ProjectRequestTemplate, err)
588 588
 		return
589 589
 	}
590 590
 }
591 591
 
592
-// ensureMasterAuthorizationNamespace is called as part of global policy initialization to ensure master namespace exists
593
-func (c *MasterConfig) ensureMasterAuthorizationNamespace() {
594
-
595
-	// ensure that master namespace actually exists
596
-	namespace, err := c.KubeClient().Namespaces().Get(c.Options.PolicyConfig.MasterAuthorizationNamespace)
597
-	if err != nil {
598
-		namespace = &kapi.Namespace{
599
-			ObjectMeta: kapi.ObjectMeta{Name: c.Options.PolicyConfig.MasterAuthorizationNamespace},
600
-			Spec: kapi.NamespaceSpec{
601
-				Finalizers: []kapi.FinalizerName{projectapi.FinalizerProject},
602
-			},
603
-		}
604
-		kapi.FillObjectMetaSystemFields(api.NewContext(), &namespace.ObjectMeta)
605
-		_, err = c.KubeClient().Namespaces().Create(namespace)
606
-		if err != nil {
607
-			glog.Errorf("Error creating namespace: %v due to %v\n", namespace, err)
608
-		}
609
-	}
610
-}
611
-
612 592
 // ensureOpenShiftSharedResourcesNamespace is called as part of global policy initialization to ensure shared namespace exists
613 593
 func (c *MasterConfig) ensureOpenShiftSharedResourcesNamespace() {
614 594
 	namespace, err := c.KubeClient().Namespaces().Get(c.Options.PolicyConfig.OpenShiftSharedResourcesNamespace)
... ...
@@ -629,13 +618,13 @@ func (c *MasterConfig) ensureOpenShiftSharedResourcesNamespace() {
629 629
 
630 630
 // ensureComponentAuthorizationRules initializes the global policies
631 631
 func (c *MasterConfig) ensureComponentAuthorizationRules() {
632
-	policyRegistry := policyregistry.NewRegistry(policyetcd.NewStorage(c.EtcdHelper))
633
-	ctx := kapi.WithNamespace(kapi.NewContext(), c.Options.PolicyConfig.MasterAuthorizationNamespace)
632
+	clusterPolicyRegistry := clusterpolicyregistry.NewRegistry(clusterpolicystorage.NewStorage(c.EtcdHelper))
633
+	ctx := kapi.WithNamespace(kapi.NewContext(), "")
634 634
 
635
-	if _, err := policyRegistry.GetPolicy(ctx, authorizationapi.PolicyName); kapierror.IsNotFound(err) {
635
+	if _, err := clusterPolicyRegistry.GetClusterPolicy(ctx, authorizationapi.PolicyName); kapierror.IsNotFound(err) {
636 636
 		glog.Infof("No master policy found.  Creating bootstrap policy based on: %v", c.Options.PolicyConfig.BootstrapPolicyFile)
637 637
 
638
-		if err := admin.OverwriteBootstrapPolicy(c.EtcdHelper, c.Options.PolicyConfig.MasterAuthorizationNamespace, c.Options.PolicyConfig.BootstrapPolicyFile, admin.CreateBootstrapPolicyFileFullCommand, true, ioutil.Discard); err != nil {
638
+		if err := admin.OverwriteBootstrapPolicy(c.EtcdHelper, c.Options.PolicyConfig.BootstrapPolicyFile, admin.CreateBootstrapPolicyFileFullCommand, true, ioutil.Discard); err != nil {
639 639
 			glog.Errorf("Error creating bootstrap policy: %v", err)
640 640
 		}
641 641
 
... ...
@@ -25,6 +25,10 @@ import (
25 25
 	authnregistry "github.com/openshift/origin/pkg/auth/oauth/registry"
26 26
 	"github.com/openshift/origin/pkg/authorization/authorizer"
27 27
 	policycache "github.com/openshift/origin/pkg/authorization/cache"
28
+	clusterpolicyregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy"
29
+	clusterpolicyetcd "github.com/openshift/origin/pkg/authorization/registry/clusterpolicy/etcd"
30
+	clusterpolicybindingregistry "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding"
31
+	clusterpolicybindingetcd "github.com/openshift/origin/pkg/authorization/registry/clusterpolicybinding/etcd"
28 32
 	policyregistry "github.com/openshift/origin/pkg/authorization/registry/policy"
29 33
 	policyetcd "github.com/openshift/origin/pkg/authorization/registry/policy/etcd"
30 34
 	policybindingregistry "github.com/openshift/origin/pkg/authorization/registry/policybinding"
... ...
@@ -141,11 +145,11 @@ func BuildMasterConfig(options configapi.MasterConfig) (*MasterConfig, error) {
141 141
 		Options: options,
142 142
 
143 143
 		Authenticator:                 newAuthenticator(options.ServingInfo, etcdHelper, apiClientCAs),
144
-		Authorizer:                    newAuthorizer(policyCache, options.PolicyConfig.MasterAuthorizationNamespace),
144
+		Authorizer:                    newAuthorizer(policyCache),
145 145
 		AuthorizationAttributeBuilder: newAuthorizationAttributeBuilder(requestContextMapper),
146 146
 
147 147
 		PolicyCache:               policyCache,
148
-		ProjectAuthorizationCache: newProjectAuthorizationCache(options.PolicyConfig.MasterAuthorizationNamespace, privilegedLoopbackOpenShiftClient, privilegedLoopbackKubeClient),
148
+		ProjectAuthorizationCache: newProjectAuthorizationCache(privilegedLoopbackOpenShiftClient, privilegedLoopbackKubeClient),
149 149
 
150 150
 		RequestContextMapper: requestContextMapper,
151 151
 
... ...
@@ -203,23 +207,26 @@ func newAuthenticator(servingInfo configapi.ServingInfo, etcdHelper tools.EtcdHe
203 203
 	return ret
204 204
 }
205 205
 
206
-func newProjectAuthorizationCache(masterAuthorizationNamespace string, openshiftClient *osclient.Client, kubeClient *kclient.Client) *projectauth.AuthorizationCache {
206
+func newProjectAuthorizationCache(openshiftClient *osclient.Client, kubeClient *kclient.Client) *projectauth.AuthorizationCache {
207 207
 	return projectauth.NewAuthorizationCache(
208 208
 		projectauth.NewReviewer(openshiftClient),
209 209
 		kubeClient.Namespaces(),
210 210
 		openshiftClient,
211 211
 		openshiftClient,
212
-		masterAuthorizationNamespace)
212
+		"dead-value")
213 213
 }
214 214
 
215 215
 func newPolicyCache(etcdHelper tools.EtcdHelper) *policycache.PolicyCache {
216 216
 	policyRegistry := policyregistry.NewRegistry(policyetcd.NewStorage(etcdHelper))
217 217
 	policyBindingRegistry := policybindingregistry.NewRegistry(policybindingetcd.NewStorage(etcdHelper))
218
-	return policycache.NewPolicyCache(policyBindingRegistry, policyRegistry)
218
+	clusterPolicyRegistry := clusterpolicyregistry.NewRegistry(clusterpolicyetcd.NewStorage(etcdHelper))
219
+	clusterPolicyBindingRegistry := clusterpolicybindingregistry.NewRegistry(clusterpolicybindingetcd.NewStorage(etcdHelper))
220
+
221
+	return policycache.NewPolicyCache(policyBindingRegistry, policyRegistry, clusterPolicyBindingRegistry, clusterPolicyRegistry)
219 222
 }
220 223
 
221
-func newAuthorizer(policyCache *policycache.PolicyCache, masterAuthorizationNamespace string) authorizer.Authorizer {
222
-	authorizer := authorizer.NewAuthorizer(masterAuthorizationNamespace, rulevalidation.NewDefaultRuleResolver(policyCache, policyCache))
224
+func newAuthorizer(policyCache *policycache.PolicyCache) authorizer.Authorizer {
225
+	authorizer := authorizer.NewAuthorizer(rulevalidation.NewDefaultRuleResolver(policyCache, policyCache, policyCache, policyCache))
223 226
 	return authorizer
224 227
 }
225 228
 
... ...
@@ -184,7 +184,6 @@ func (args MasterArgs) BuildSerializeableMasterConfig() (*configapi.MasterConfig
184 184
 
185 185
 		PolicyConfig: configapi.PolicyConfig{
186 186
 			BootstrapPolicyFile:               args.GetPolicyFile(),
187
-			MasterAuthorizationNamespace:      bootstrappolicy.DefaultMasterAuthorizationNamespace,
188 187
 			OpenShiftSharedResourcesNamespace: bootstrappolicy.DefaultOpenShiftSharedResourcesNamespace,
189 188
 		},
190 189
 
... ...
@@ -250,7 +250,6 @@ func (o MasterOptions) RunMaster() error {
250 250
 func (o MasterOptions) CreateBootstrapPolicy() error {
251 251
 	writeBootstrapPolicy := admin.CreateBootstrapPolicyFileOptions{
252 252
 		File: o.MasterArgs.GetPolicyFile(),
253
-		MasterAuthorizationNamespace:      bootstrappolicy.DefaultMasterAuthorizationNamespace,
254 253
 		OpenShiftSharedResourcesNamespace: bootstrappolicy.DefaultOpenShiftSharedResourcesNamespace,
255 254
 	}
256 255
 
... ...
@@ -16,11 +16,9 @@ import (
16 16
 
17 17
 	"github.com/openshift/origin/pkg/api/latest"
18 18
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
19
-	"github.com/openshift/origin/pkg/authorization/registry/rolebinding"
20 19
 	"github.com/openshift/origin/pkg/client"
21 20
 	configcmd "github.com/openshift/origin/pkg/config/cmd"
22 21
 	projectapi "github.com/openshift/origin/pkg/project/api"
23
-	projectstorage "github.com/openshift/origin/pkg/project/registry/project/proxy"
24 22
 	projectrequestregistry "github.com/openshift/origin/pkg/project/registry/projectrequest"
25 23
 )
26 24
 
... ...
@@ -28,19 +26,15 @@ type REST struct {
28 28
 	message            string
29 29
 	openshiftNamespace string
30 30
 	templateName       string
31
-	roleBindingStorage rolebinding.Storage
32 31
 
33
-	projectStorage  projectstorage.REST
34 32
 	openshiftClient *client.Client
35 33
 }
36 34
 
37
-func NewREST(message, openshiftNamespace, templateName string, roleBindingStorage rolebinding.Storage, projectStorage projectstorage.REST, openshiftClient *client.Client) *REST {
35
+func NewREST(message, openshiftNamespace, templateName string, openshiftClient *client.Client) *REST {
38 36
 	return &REST{
39 37
 		message:            message,
40 38
 		openshiftNamespace: openshiftNamespace,
41 39
 		templateName:       templateName,
42
-		roleBindingStorage: roleBindingStorage,
43
-		projectStorage:     projectStorage,
44 40
 		openshiftClient:    openshiftClient,
45 41
 	}
46 42
 }
... ...
@@ -21,7 +21,7 @@ var (
21 21
 	parameters = []string{ProjectNameParam, ProjectDisplayNameParam, ProjectDescriptionParam, ProjectAdminUserParam}
22 22
 )
23 23
 
24
-func NewSampleTemplate(masterNamespace, openshiftNamespace, templateName string) *templateapi.Template {
24
+func NewSampleTemplate(openshiftNamespace, templateName string) *templateapi.Template {
25 25
 	ret := &templateapi.Template{}
26 26
 	ret.Name = templateName
27 27
 	ret.Namespace = openshiftNamespace
... ...
@@ -38,7 +38,6 @@ func NewSampleTemplate(masterNamespace, openshiftNamespace, templateName string)
38 38
 	binding.Name = "admins"
39 39
 	binding.Namespace = "${" + ProjectNameParam + "}"
40 40
 	binding.Users = util.NewStringSet("${" + ProjectAdminUserParam + "}")
41
-	binding.RoleRef.Namespace = masterNamespace
42 41
 	binding.RoleRef.Name = bootstrappolicy.AdminRoleName
43 42
 	ret.Objects = append(ret.Objects, binding)
44 43
 
... ...
@@ -103,26 +103,24 @@ func TestOnlyResolveRolesForBindingsThatMatter(t *testing.T) {
103 103
 	}
104 104
 
105 105
 	addValerie := &policy.RoleModificationOptions{
106
-		RoleNamespace:    bootstrappolicy.DefaultMasterAuthorizationNamespace,
107
-		RoleName:         bootstrappolicy.ViewRoleName,
108
-		BindingNamespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
109
-		Client:           clusterAdminClient,
110
-		Users:            []string{"valerie"},
106
+		RoleNamespace:       "",
107
+		RoleName:            bootstrappolicy.ViewRoleName,
108
+		RoleBindingAccessor: policy.NewClusterRoleBindingAccessor(clusterAdminClient),
109
+		Users:               []string{"valerie"},
111 110
 	}
112 111
 	if err := addValerie.AddRole(); err != nil {
113 112
 		t.Fatalf("unexpected error: %v", err)
114 113
 	}
115 114
 
116
-	if err = clusterAdminClient.Roles(bootstrappolicy.DefaultMasterAuthorizationNamespace).Delete(bootstrappolicy.ViewRoleName); err != nil {
115
+	if err = clusterAdminClient.ClusterRoles().Delete(bootstrappolicy.ViewRoleName); err != nil {
117 116
 		t.Fatalf("unexpected error: %v", err)
118 117
 	}
119 118
 
120 119
 	addEdgar := &policy.RoleModificationOptions{
121
-		RoleNamespace:    bootstrappolicy.DefaultMasterAuthorizationNamespace,
122
-		RoleName:         bootstrappolicy.EditRoleName,
123
-		BindingNamespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
124
-		Client:           clusterAdminClient,
125
-		Users:            []string{"edgar"},
120
+		RoleNamespace:       "",
121
+		RoleName:            bootstrappolicy.EditRoleName,
122
+		RoleBindingAccessor: policy.NewClusterRoleBindingAccessor(clusterAdminClient),
123
+		Users:               []string{"edgar"},
126 124
 	}
127 125
 	if err := addEdgar.AddRole(); err != nil {
128 126
 		t.Fatalf("unexpected error: %v", err)
... ...
@@ -193,22 +191,20 @@ func TestResourceAccessReview(t *testing.T) {
193 193
 	}
194 194
 
195 195
 	addValerie := &policy.RoleModificationOptions{
196
-		RoleNamespace:    bootstrappolicy.DefaultMasterAuthorizationNamespace,
197
-		RoleName:         bootstrappolicy.ViewRoleName,
198
-		BindingNamespace: "hammer-project",
199
-		Client:           haroldClient,
200
-		Users:            []string{"valerie"},
196
+		RoleNamespace:       "",
197
+		RoleName:            bootstrappolicy.ViewRoleName,
198
+		RoleBindingAccessor: policy.NewLocalRoleBindingAccessor("hammer-project", haroldClient),
199
+		Users:               []string{"valerie"},
201 200
 	}
202 201
 	if err := addValerie.AddRole(); err != nil {
203 202
 		t.Fatalf("unexpected error: %v", err)
204 203
 	}
205 204
 
206 205
 	addEdgar := &policy.RoleModificationOptions{
207
-		RoleNamespace:    bootstrappolicy.DefaultMasterAuthorizationNamespace,
208
-		RoleName:         bootstrappolicy.EditRoleName,
209
-		BindingNamespace: "mallet-project",
210
-		Client:           markClient,
211
-		Users:            []string{"edgar"},
206
+		RoleNamespace:       "",
207
+		RoleName:            bootstrappolicy.EditRoleName,
208
+		RoleBindingAccessor: policy.NewLocalRoleBindingAccessor("mallet-project", markClient),
209
+		Users:               []string{"edgar"},
212 210
 	}
213 211
 	if err := addEdgar.AddRole(); err != nil {
214 212
 		t.Fatalf("unexpected error: %v", err)
... ...
@@ -321,22 +317,20 @@ func TestSubjectAccessReview(t *testing.T) {
321 321
 	}
322 322
 
323 323
 	addValerie := &policy.RoleModificationOptions{
324
-		RoleNamespace:    bootstrappolicy.DefaultMasterAuthorizationNamespace,
325
-		RoleName:         bootstrappolicy.ViewRoleName,
326
-		BindingNamespace: "hammer-project",
327
-		Client:           haroldClient,
328
-		Users:            []string{"valerie"},
324
+		RoleNamespace:       "",
325
+		RoleName:            bootstrappolicy.ViewRoleName,
326
+		RoleBindingAccessor: policy.NewLocalRoleBindingAccessor("hammer-project", haroldClient),
327
+		Users:               []string{"valerie"},
329 328
 	}
330 329
 	if err := addValerie.AddRole(); err != nil {
331 330
 		t.Errorf("unexpected error: %v", err)
332 331
 	}
333 332
 
334 333
 	addEdgar := &policy.RoleModificationOptions{
335
-		RoleNamespace:    bootstrappolicy.DefaultMasterAuthorizationNamespace,
336
-		RoleName:         bootstrappolicy.EditRoleName,
337
-		BindingNamespace: "mallet-project",
338
-		Client:           markClient,
339
-		Users:            []string{"edgar"},
334
+		RoleNamespace:       "",
335
+		RoleName:            bootstrappolicy.EditRoleName,
336
+		RoleBindingAccessor: policy.NewLocalRoleBindingAccessor("mallet-project", markClient),
337
+		Users:               []string{"edgar"},
340 338
 	}
341 339
 	if err := addEdgar.AddRole(); err != nil {
342 340
 		t.Fatalf("unexpected error: %v", err)
... ...
@@ -87,11 +87,11 @@ func TestOverwritePolicyCommand(t *testing.T) {
87 87
 		t.Errorf("unexpected error: %v", err)
88 88
 	}
89 89
 
90
-	if err := client.Policies(masterConfig.PolicyConfig.MasterAuthorizationNamespace).Delete(authorizationapi.PolicyName); err != nil {
90
+	if err := client.ClusterPolicies().Delete(authorizationapi.PolicyName); err != nil {
91 91
 		t.Errorf("unexpected error: %v", err)
92 92
 	}
93 93
 
94
-	if _, err := client.Policies(masterConfig.PolicyConfig.MasterAuthorizationNamespace).List(labels.Everything(), fields.Everything()); err == nil || !kapierror.IsForbidden(err) {
94
+	if _, err := client.ClusterPolicies().List(labels.Everything(), fields.Everything()); err == nil || !kapierror.IsForbidden(err) {
95 95
 		t.Errorf("unexpected error: %v", err)
96 96
 	}
97 97
 
... ...
@@ -105,11 +105,11 @@ func TestOverwritePolicyCommand(t *testing.T) {
105 105
 		t.Errorf("unexpected error: %v", err)
106 106
 	}
107 107
 
108
-	if err := admin.OverwriteBootstrapPolicy(etcdHelper, masterConfig.PolicyConfig.MasterAuthorizationNamespace, masterConfig.PolicyConfig.BootstrapPolicyFile, admin.CreateBootstrapPolicyFileFullCommand, true, ioutil.Discard); err != nil {
108
+	if err := admin.OverwriteBootstrapPolicy(etcdHelper, masterConfig.PolicyConfig.BootstrapPolicyFile, admin.CreateBootstrapPolicyFileFullCommand, true, ioutil.Discard); err != nil {
109 109
 		t.Errorf("unexpected error: %v", err)
110 110
 	}
111 111
 
112
-	if _, err := client.Policies(masterConfig.PolicyConfig.MasterAuthorizationNamespace).List(labels.Everything(), fields.Everything()); err != nil {
112
+	if _, err := client.ClusterPolicies().List(labels.Everything(), fields.Everything()); err != nil {
113 113
 		t.Errorf("unexpected error: %v", err)
114 114
 	}
115 115
 }
... ...
@@ -66,11 +66,10 @@ func TestLogin(t *testing.T) {
66 66
 	}
67 67
 
68 68
 	newProjectOptions := &newproject.NewProjectOptions{
69
-		Client:                clusterAdminClient,
70
-		ProjectName:           project,
71
-		AdminRole:             bootstrappolicy.AdminRoleName,
72
-		MasterPolicyNamespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
73
-		AdminUser:             username,
69
+		Client:      clusterAdminClient,
70
+		ProjectName: project,
71
+		AdminRole:   bootstrappolicy.AdminRoleName,
72
+		AdminUser:   username,
74 73
 	}
75 74
 	if err := newProjectOptions.Run(); err != nil {
76 75
 		t.Fatalf("unexpected error, a project is required to continue: %v", err)
... ...
@@ -108,12 +108,14 @@ func TestDeniedUnprivilegedNewProject(t *testing.T) {
108 108
 	if err != nil {
109 109
 		t.Errorf("unexpected error: %v", err)
110 110
 	}
111
-	role, err := clusterAdminClient.Roles("master").Get(bootstrappolicy.SelfProvisionerRoleName)
111
+	role, err := clusterAdminClient.ClusterRoles().Get(bootstrappolicy.SelfProvisionerRoleName)
112 112
 	if err != nil {
113 113
 		t.Errorf("unexpected error: %v", err)
114 114
 	}
115 115
 	role.Rules = []authorizationapi.PolicyRule{}
116
-	clusterAdminClient.Roles("master").Update(role)
116
+	if _, err := clusterAdminClient.ClusterRoles().Update(role); err != nil {
117
+		t.Errorf("unexpected error: %v", err)
118
+	}
117 119
 
118 120
 	clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig)
119 121
 	if err != nil {
... ...
@@ -146,7 +148,7 @@ func TestDeniedUnprivilegedNewProject(t *testing.T) {
146 146
 		t.Errorf("expected error: %v", err)
147 147
 	}
148 148
 	expectedError := `ProjectRequest "" is forbidden: You may not request a new project via this API.`
149
-	if err.Error() != expectedError {
149
+	if (err != nil) && (err.Error() != expectedError) {
150 150
 		t.Errorf("expected %v, got %v", expectedError, allowed.Status)
151 151
 	}
152 152
 
... ...
@@ -101,7 +101,6 @@ func DefaultMasterOptions() (*configapi.MasterConfig, error) {
101 101
 func CreateBootstrapPolicy(masterArgs *start.MasterArgs) error {
102 102
 	createBootstrapPolicy := &admin.CreateBootstrapPolicyFileOptions{
103 103
 		File: path.Join(masterArgs.ConfigDir.Value(), "policy.json"),
104
-		MasterAuthorizationNamespace:      "master",
105 104
 		OpenShiftSharedResourcesNamespace: "openshift",
106 105
 	}
107 106
 
... ...
@@ -255,7 +254,7 @@ func StartConfiguredMaster(masterConfig *configapi.MasterConfig) (string, error)
255 255
 	for {
256 256
 		// confirm that we can actually query from the api server
257 257
 		if client, err := GetClusterAdminClient(adminKubeConfigFile); err == nil {
258
-			if _, err := client.Policies(bootstrappolicy.DefaultMasterAuthorizationNamespace).List(labels.Everything(), fields.Everything()); err == nil {
258
+			if _, err := client.ClusterPolicies().List(labels.Everything(), fields.Everything()); err == nil {
259 259
 				break
260 260
 			}
261 261
 		}
... ...
@@ -280,11 +279,10 @@ func StartTestMaster() (*configapi.MasterConfig, string, error) {
280 280
 // back a client for the admin user
281 281
 func CreateNewProject(clusterAdminClient *client.Client, clientConfig kclient.Config, projectName, adminUser string) (*client.Client, error) {
282 282
 	newProjectOptions := &newproject.NewProjectOptions{
283
-		Client:                clusterAdminClient,
284
-		ProjectName:           projectName,
285
-		AdminRole:             bootstrappolicy.AdminRoleName,
286
-		MasterPolicyNamespace: bootstrappolicy.DefaultMasterAuthorizationNamespace,
287
-		AdminUser:             adminUser,
283
+		Client:      clusterAdminClient,
284
+		ProjectName: projectName,
285
+		AdminRole:   bootstrappolicy.AdminRoleName,
286
+		AdminUser:   adminUser,
288 287
 	}
289 288
 
290 289
 	if err := newProjectOptions.Run(); err != nil {