| ... | ... |
@@ -76,6 +76,7 @@ var originTypes = []string{
|
| 76 | 76 |
"Project", |
| 77 | 77 |
"User", "UserIdentityMapping", |
| 78 | 78 |
"OAuthClient", "OAuthClientAuthorization", "OAuthAccessToken", "OAuthAuthorizeToken", |
| 79 |
+ "Role", "RoleBinding", "Policy", "PolicyBinding", |
|
| 79 | 80 |
} |
| 80 | 81 |
|
| 81 | 82 |
// OriginKind returns true if OpenShift owns the kind described in a given apiVersion. |
| ... | ... |
@@ -4,6 +4,7 @@ import ( |
| 4 | 4 |
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" |
| 5 | 5 |
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" |
| 6 | 6 |
|
| 7 |
+ _ "github.com/openshift/origin/pkg/authorization/api" |
|
| 7 | 8 |
_ "github.com/openshift/origin/pkg/build/api" |
| 8 | 9 |
_ "github.com/openshift/origin/pkg/config/api" |
| 9 | 10 |
_ "github.com/openshift/origin/pkg/deploy/api" |
| ... | ... |
@@ -18,6 +18,7 @@ import ( |
| 18 | 18 |
osapi "github.com/openshift/origin/pkg/api" |
| 19 | 19 |
_ "github.com/openshift/origin/pkg/api/latest" |
| 20 | 20 |
"github.com/openshift/origin/pkg/api/v1beta1" |
| 21 |
+ authorizationapi "github.com/openshift/origin/pkg/authorization/api" |
|
| 21 | 22 |
config "github.com/openshift/origin/pkg/config/api" |
| 22 | 23 |
image "github.com/openshift/origin/pkg/image/api" |
| 23 | 24 |
template "github.com/openshift/origin/pkg/template/api" |
| ... | ... |
@@ -42,6 +43,9 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs( |
| 42 | 42 |
j.APIVersion = "" |
| 43 | 43 |
j.Kind = "" |
| 44 | 44 |
}, |
| 45 |
+ func(j *runtime.EmbeddedObject, c fuzz.Continue) {
|
|
| 46 |
+ // runtime.EmbeddedObject causes a panic inside of fuzz because runtime.Object isn't handled. |
|
| 47 |
+ }, |
|
| 45 | 48 |
func(j *api.ObjectMeta, c fuzz.Continue) {
|
| 46 | 49 |
// We have to customize the randomization of TypeMetas because their |
| 47 | 50 |
// APIVersion and Kind must remain blank in memory. |
| ... | ... |
@@ -73,6 +77,13 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs( |
| 73 | 73 |
c.Fuzz(&j.Selector) |
| 74 | 74 |
j.Replicas = int(c.RandUint64()) |
| 75 | 75 |
}, |
| 76 |
+ // Roles and RoleBindings maps are never nil |
|
| 77 |
+ func(j *authorizationapi.Policy, c fuzz.Continue) {
|
|
| 78 |
+ j.Roles = make(map[string]authorizationapi.Role) |
|
| 79 |
+ }, |
|
| 80 |
+ func(j *authorizationapi.PolicyBinding, c fuzz.Continue) {
|
|
| 81 |
+ j.RoleBindings = make(map[string]authorizationapi.RoleBinding) |
|
| 82 |
+ }, |
|
| 76 | 83 |
func(j *template.Template, c fuzz.Continue) {
|
| 77 | 84 |
c.Fuzz(&j.ObjectMeta) |
| 78 | 85 |
c.Fuzz(&j.Parameters) |
| ... | ... |
@@ -4,6 +4,7 @@ import ( |
| 4 | 4 |
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" |
| 5 | 5 |
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" |
| 6 | 6 |
|
| 7 |
+ _ "github.com/openshift/origin/pkg/authorization/api/v1beta1" |
|
| 7 | 8 |
_ "github.com/openshift/origin/pkg/build/api/v1beta1" |
| 8 | 9 |
_ "github.com/openshift/origin/pkg/config/api/v1beta1" |
| 9 | 10 |
_ "github.com/openshift/origin/pkg/deploy/api/v1beta1" |
| 10 | 11 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,23 @@ |
| 0 |
+package api |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/GoogleCloudPlatform/kubernetes/pkg/api" |
|
| 4 |
+) |
|
| 5 |
+ |
|
| 6 |
+func init() {
|
|
| 7 |
+ api.Scheme.AddKnownTypes("",
|
|
| 8 |
+ &Role{},
|
|
| 9 |
+ &RoleBinding{},
|
|
| 10 |
+ &Policy{},
|
|
| 11 |
+ &PolicyBinding{},
|
|
| 12 |
+ &PolicyList{},
|
|
| 13 |
+ &PolicyBindingList{},
|
|
| 14 |
+ ) |
|
| 15 |
+} |
|
| 16 |
+ |
|
| 17 |
+func (*Role) IsAnAPIObject() {}
|
|
| 18 |
+func (*Policy) IsAnAPIObject() {}
|
|
| 19 |
+func (*PolicyBinding) IsAnAPIObject() {}
|
|
| 20 |
+func (*RoleBinding) IsAnAPIObject() {}
|
|
| 21 |
+func (*PolicyList) IsAnAPIObject() {}
|
|
| 22 |
+func (*PolicyBindingList) IsAnAPIObject() {}
|
| 0 | 23 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,103 @@ |
| 0 |
+package api |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api" |
|
| 4 |
+ kruntime "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" |
|
| 5 |
+ kutil "github.com/GoogleCloudPlatform/kubernetes/pkg/util" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+// Authorization is calculated against |
|
| 9 |
+// 1. all deny RoleBinding PolicyRules in the master namespace - short circuit on match |
|
| 10 |
+// 2. all allow RoleBinding PolicyRules in the master namespace - short circuit on match |
|
| 11 |
+// 3. all deny RoleBinding PolicyRules in the namespace - short circuit on match |
|
| 12 |
+// 4. all allow RoleBinding PolicyRules in the namespace - short circuit on match |
|
| 13 |
+// 5. deny by default |
|
| 14 |
+ |
|
| 15 |
+const ( |
|
| 16 |
+ // Policy is a singleton and this is its name |
|
| 17 |
+ PolicyName = "default" |
|
| 18 |
+ ResourceAll = "*" |
|
| 19 |
+ VerbAll = "*" |
|
| 20 |
+) |
|
| 21 |
+ |
|
| 22 |
+// PolicyRule holds information that describes a policy rule, but does not contain information |
|
| 23 |
+// about who the rule applies to or which namespace the rule applies to. |
|
| 24 |
+type PolicyRule struct {
|
|
| 25 |
+ // Deny is true if any request matching this rule should be denied. If false, any request matching this rule is allowed. |
|
| 26 |
+ Deny bool `json:"deny"` |
|
| 27 |
+ // Verbs is a list of Verbs that apply to ALL the ResourceKinds and AttributeRestrictions contained in this rule. VerbAll represents all kinds. |
|
| 28 |
+ Verbs []string `json:"verbs"` |
|
| 29 |
+ // AttributeRestrictions will vary depending on what the Authorizer/AuthorizationAttributeBuilder pair supports. |
|
| 30 |
+ // If the Authorizer does not recognize how to handle the AttributeRestrictions, the Authorizer should report an error. |
|
| 31 |
+ AttributeRestrictions kruntime.EmbeddedObject `json:"attributeRestrictions"` |
|
| 32 |
+ // ResourceKinds is a list of kinds this rule applies to. ResourceAll represents all kinds. |
|
| 33 |
+ ResourceKinds []string `json:"resourceKinds"` |
|
| 34 |
+} |
|
| 35 |
+ |
|
| 36 |
+// Role is a logical grouping of PolicyRules that can be referenced as a unit by RoleBindings. |
|
| 37 |
+type Role struct {
|
|
| 38 |
+ kapi.TypeMeta `json:",inline"` |
|
| 39 |
+ kapi.ObjectMeta `json:"metadata,omitempty"` |
|
| 40 |
+ |
|
| 41 |
+ // Rules holds all the PolicyRules for this Role |
|
| 42 |
+ Rules []PolicyRule `json:"rules"` |
|
| 43 |
+} |
|
| 44 |
+ |
|
| 45 |
+// RoleBinding references a Role, but not contain it. It adds who and namespace information. |
|
| 46 |
+// It can reference any Role in the same namespace or in the global namespace. |
|
| 47 |
+type RoleBinding struct {
|
|
| 48 |
+ kapi.TypeMeta `json:",inline"` |
|
| 49 |
+ kapi.ObjectMeta `json:"metadata,omitempty"` |
|
| 50 |
+ |
|
| 51 |
+ // UserNames holds all the usernames directly bound to the role |
|
| 52 |
+ UserNames []string `json:"userNames"` |
|
| 53 |
+ // GroupNames holds all the groups directly bound to the role |
|
| 54 |
+ GroupNames []string `json:"groupNames"` |
|
| 55 |
+ |
|
| 56 |
+ // Since Policy is a singleton, this is sufficient knowledge to locate a role |
|
| 57 |
+ // RoleRefs can only reference the current namespace and the global namespace |
|
| 58 |
+ // If the RoleRef cannot be resolved, the Authorizer must return an error. |
|
| 59 |
+ RoleRef kapi.ObjectReference `json:"roleRef"` |
|
| 60 |
+} |
|
| 61 |
+ |
|
| 62 |
+// Policy is a object that holds all the Roles for a particular namespace. There is at most |
|
| 63 |
+// one Policy document per namespace. |
|
| 64 |
+type Policy struct {
|
|
| 65 |
+ kapi.TypeMeta `json:",inline"` |
|
| 66 |
+ kapi.ObjectMeta `json:"metadata,omitempty" ` |
|
| 67 |
+ |
|
| 68 |
+ // LastModified is the last time that any part of the Policy was created, updated, or deleted |
|
| 69 |
+ LastModified kutil.Time `json:"lastModified"` |
|
| 70 |
+ |
|
| 71 |
+ // Roles holds all the Roles held by this Policy, mapped by Role.Name |
|
| 72 |
+ Roles map[string]Role `json:"roles"` |
|
| 73 |
+} |
|
| 74 |
+ |
|
| 75 |
+// PolicyBinding is a object that holds all the RoleBindings for a particular namespace. There is |
|
| 76 |
+// one PolicyBinding document per referenced Policy namespace |
|
| 77 |
+type PolicyBinding struct {
|
|
| 78 |
+ kapi.TypeMeta `json:",inline"` |
|
| 79 |
+ kapi.ObjectMeta `json:"metadata,omitempty"` |
|
| 80 |
+ |
|
| 81 |
+ // LastModified is the last time that any part of the PolicyBinding was created, updated, or deleted |
|
| 82 |
+ LastModified kutil.Time `json:"lastModified"` |
|
| 83 |
+ |
|
| 84 |
+ // PolicyRef is a reference to the Policy that contains all the Roles that this PolicyBinding's RoleBindings may reference |
|
| 85 |
+ PolicyRef kapi.ObjectReference `json:"policyRef"` |
|
| 86 |
+ // RoleBindings holds all the RoleBindings held by this PolicyBinding, mapped by RoleBinding.Name |
|
| 87 |
+ RoleBindings map[string]RoleBinding `json:"roleBindings"` |
|
| 88 |
+} |
|
| 89 |
+ |
|
| 90 |
+// PolicyList is a collection of Policies |
|
| 91 |
+type PolicyList struct {
|
|
| 92 |
+ kapi.TypeMeta `json:",inline"` |
|
| 93 |
+ kapi.ListMeta `json:"metadata,omitempty"` |
|
| 94 |
+ Items []Policy `json:"items"` |
|
| 95 |
+} |
|
| 96 |
+ |
|
| 97 |
+// PolicyBindingList is a collection of PolicyBindings |
|
| 98 |
+type PolicyBindingList struct {
|
|
| 99 |
+ kapi.TypeMeta `json:",inline"` |
|
| 100 |
+ kapi.ListMeta `json:"metadata,omitempty"` |
|
| 101 |
+ Items []PolicyBinding `json:"items"` |
|
| 102 |
+} |
| 0 | 103 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,117 @@ |
| 0 |
+/* |
|
| 1 |
+Copyright 2014 Google Inc. All rights reserved. |
|
| 2 |
+ |
|
| 3 |
+Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 4 |
+you may not use this file except in compliance with the License. |
|
| 5 |
+You may obtain a copy of the License at |
|
| 6 |
+ |
|
| 7 |
+ http://www.apache.org/licenses/LICENSE-2.0 |
|
| 8 |
+ |
|
| 9 |
+Unless required by applicable law or agreed to in writing, software |
|
| 10 |
+distributed under the License is distributed on an "AS IS" BASIS, |
|
| 11 |
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 12 |
+See the License for the specific language governing permissions and |
|
| 13 |
+limitations under the License. |
|
| 14 |
+*/ |
|
| 15 |
+ |
|
| 16 |
+package v1beta1 |
|
| 17 |
+ |
|
| 18 |
+import ( |
|
| 19 |
+ "sort" |
|
| 20 |
+ |
|
| 21 |
+ "github.com/GoogleCloudPlatform/kubernetes/pkg/conversion" |
|
| 22 |
+ |
|
| 23 |
+ "github.com/GoogleCloudPlatform/kubernetes/pkg/api" |
|
| 24 |
+ newer "github.com/openshift/origin/pkg/authorization/api" |
|
| 25 |
+) |
|
| 26 |
+ |
|
| 27 |
+func init() {
|
|
| 28 |
+ err := api.Scheme.AddConversionFuncs( |
|
| 29 |
+ func(in *Policy, out *newer.Policy, s conversion.Scope) error {
|
|
| 30 |
+ out.LastModified = in.LastModified |
|
| 31 |
+ out.Roles = make(map[string]newer.Role) |
|
| 32 |
+ return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) |
|
| 33 |
+ }, |
|
| 34 |
+ func(in *newer.Policy, out *Policy, s conversion.Scope) error {
|
|
| 35 |
+ out.LastModified = in.LastModified |
|
| 36 |
+ out.Roles = make([]NamedRole, 0, 0) |
|
| 37 |
+ return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) |
|
| 38 |
+ }, |
|
| 39 |
+ func(in *[]NamedRole, out *map[string]newer.Role, s conversion.Scope) error {
|
|
| 40 |
+ for _, curr := range *in {
|
|
| 41 |
+ newRole := &newer.Role{}
|
|
| 42 |
+ if err := s.Convert(&curr.Role, newRole, 0); err != nil {
|
|
| 43 |
+ return err |
|
| 44 |
+ } |
|
| 45 |
+ (*out)[curr.Name] = *newRole |
|
| 46 |
+ } |
|
| 47 |
+ |
|
| 48 |
+ return nil |
|
| 49 |
+ }, |
|
| 50 |
+ func(in *map[string]newer.Role, out *[]NamedRole, s conversion.Scope) error {
|
|
| 51 |
+ allKeys := make([]string, 0, len(*in)) |
|
| 52 |
+ for key := range *in {
|
|
| 53 |
+ allKeys = append(allKeys, key) |
|
| 54 |
+ } |
|
| 55 |
+ sort.Strings(allKeys) |
|
| 56 |
+ |
|
| 57 |
+ for _, key := range allKeys {
|
|
| 58 |
+ newRole := (*in)[key] |
|
| 59 |
+ oldRole := &Role{}
|
|
| 60 |
+ if err := s.Convert(&newRole, oldRole, 0); err != nil {
|
|
| 61 |
+ return err |
|
| 62 |
+ } |
|
| 63 |
+ |
|
| 64 |
+ namedRole := NamedRole{key, *oldRole}
|
|
| 65 |
+ *out = append(*out, namedRole) |
|
| 66 |
+ } |
|
| 67 |
+ |
|
| 68 |
+ return nil |
|
| 69 |
+ }, |
|
| 70 |
+ func(in *PolicyBinding, out *newer.PolicyBinding, s conversion.Scope) error {
|
|
| 71 |
+ out.LastModified = in.LastModified |
|
| 72 |
+ out.RoleBindings = make(map[string]newer.RoleBinding) |
|
| 73 |
+ return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) |
|
| 74 |
+ }, |
|
| 75 |
+ func(in *newer.PolicyBinding, out *PolicyBinding, s conversion.Scope) error {
|
|
| 76 |
+ out.LastModified = in.LastModified |
|
| 77 |
+ out.RoleBindings = make([]NamedRoleBinding, 0, 0) |
|
| 78 |
+ return s.DefaultConvert(in, out, conversion.IgnoreMissingFields) |
|
| 79 |
+ }, |
|
| 80 |
+ func(in *[]NamedRoleBinding, out *map[string]newer.RoleBinding, s conversion.Scope) error {
|
|
| 81 |
+ for _, curr := range *in {
|
|
| 82 |
+ newRoleBinding := &newer.RoleBinding{}
|
|
| 83 |
+ if err := s.Convert(&curr.RoleBinding, newRoleBinding, 0); err != nil {
|
|
| 84 |
+ return err |
|
| 85 |
+ } |
|
| 86 |
+ (*out)[curr.Name] = *newRoleBinding |
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ return nil |
|
| 90 |
+ }, |
|
| 91 |
+ func(in *map[string]newer.RoleBinding, out *[]NamedRoleBinding, s conversion.Scope) error {
|
|
| 92 |
+ allKeys := make([]string, 0, len(*in)) |
|
| 93 |
+ for key := range *in {
|
|
| 94 |
+ allKeys = append(allKeys, key) |
|
| 95 |
+ } |
|
| 96 |
+ sort.Strings(allKeys) |
|
| 97 |
+ |
|
| 98 |
+ for _, key := range allKeys {
|
|
| 99 |
+ newRoleBinding := (*in)[key] |
|
| 100 |
+ oldRoleBinding := &RoleBinding{}
|
|
| 101 |
+ if err := s.Convert(&newRoleBinding, oldRoleBinding, 0); err != nil {
|
|
| 102 |
+ return err |
|
| 103 |
+ } |
|
| 104 |
+ |
|
| 105 |
+ namedRoleBinding := NamedRoleBinding{key, *oldRoleBinding}
|
|
| 106 |
+ *out = append(*out, namedRoleBinding) |
|
| 107 |
+ } |
|
| 108 |
+ |
|
| 109 |
+ return nil |
|
| 110 |
+ }, |
|
| 111 |
+ ) |
|
| 112 |
+ if err != nil {
|
|
| 113 |
+ // If one of the conversion functions is malformed, detect it immediately. |
|
| 114 |
+ panic(err) |
|
| 115 |
+ } |
|
| 116 |
+} |
| 0 | 117 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,23 @@ |
| 0 |
+package v1beta1 |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "github.com/GoogleCloudPlatform/kubernetes/pkg/api" |
|
| 4 |
+) |
|
| 5 |
+ |
|
| 6 |
+func init() {
|
|
| 7 |
+ api.Scheme.AddKnownTypes("v1beta1",
|
|
| 8 |
+ &Role{},
|
|
| 9 |
+ &RoleBinding{},
|
|
| 10 |
+ &Policy{},
|
|
| 11 |
+ &PolicyBinding{},
|
|
| 12 |
+ &PolicyList{},
|
|
| 13 |
+ &PolicyBindingList{},
|
|
| 14 |
+ ) |
|
| 15 |
+} |
|
| 16 |
+ |
|
| 17 |
+func (*Role) IsAnAPIObject() {}
|
|
| 18 |
+func (*Policy) IsAnAPIObject() {}
|
|
| 19 |
+func (*PolicyBinding) IsAnAPIObject() {}
|
|
| 20 |
+func (*RoleBinding) IsAnAPIObject() {}
|
|
| 21 |
+func (*PolicyList) IsAnAPIObject() {}
|
|
| 22 |
+func (*PolicyBindingList) IsAnAPIObject() {}
|
| 0 | 23 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,106 @@ |
| 0 |
+package v1beta1 |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3" |
|
| 4 |
+ kruntime "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" |
|
| 5 |
+ kutil "github.com/GoogleCloudPlatform/kubernetes/pkg/util" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+// Authorization is calculated against |
|
| 9 |
+// 1. all deny RoleBinding PolicyRules in the master namespace - short circuit on match |
|
| 10 |
+// 2. all allow RoleBinding PolicyRules in the master namespace - short circuit on match |
|
| 11 |
+// 3. all deny RoleBinding PolicyRules in the namespace - short circuit on match |
|
| 12 |
+// 4. all allow RoleBinding PolicyRules in the namespace - short circuit on match |
|
| 13 |
+// 5. deny by default |
|
| 14 |
+ |
|
| 15 |
+// PolicyRule holds information that describes a policy rule, but does not contain information |
|
| 16 |
+// about who the rule applies to or which namespace the rule applies to. |
|
| 17 |
+type PolicyRule struct {
|
|
| 18 |
+ // Deny is true if any request matching this rule should be denied. If false, any request matching this rule is allowed. |
|
| 19 |
+ Deny bool `json:"deny"` |
|
| 20 |
+ // Verbs is a list of Verbs that apply to ALL the ResourceKinds and AttributeRestrictions contained in this rule. VerbAll represents all kinds. |
|
| 21 |
+ Verbs []string `json:"verbs"` |
|
| 22 |
+ // AttributeRestrictions will vary depending on what the Authorizer/AuthorizationAttributeBuilder pair supports. |
|
| 23 |
+ // If the Authorizer does not recognize how to handle the AttributeRestrictions, the Authorizer should report an error. |
|
| 24 |
+ AttributeRestrictions kruntime.RawExtension `json:"attributeRestrictions"` |
|
| 25 |
+ // ResourceKinds is a list of kinds this rule applies to. ResourceAll represents all kinds. |
|
| 26 |
+ ResourceKinds []string `json:"resourceKinds""` |
|
| 27 |
+} |
|
| 28 |
+ |
|
| 29 |
+// Role is a logical grouping of PolicyRules that can be referenced as a unit by RoleBindings. |
|
| 30 |
+type Role struct {
|
|
| 31 |
+ kapi.TypeMeta `json:",inline"` |
|
| 32 |
+ kapi.ObjectMeta `json:"metadata,omitempty"` |
|
| 33 |
+ |
|
| 34 |
+ // Rules holds all the PolicyRules for this Role |
|
| 35 |
+ Rules []PolicyRule `json:"rules"` |
|
| 36 |
+} |
|
| 37 |
+ |
|
| 38 |
+// RoleBinding references a Role, but not contain it. It adds who and namespace information. |
|
| 39 |
+// It can reference any Role in the same namespace or in the global namespace. |
|
| 40 |
+type RoleBinding struct {
|
|
| 41 |
+ kapi.TypeMeta `json:",inline"` |
|
| 42 |
+ kapi.ObjectMeta `json:"metadata,omitempty"` |
|
| 43 |
+ |
|
| 44 |
+ // UserNames holds all the usernames directly bound to the role |
|
| 45 |
+ UserNames []string `json:"userNames"` |
|
| 46 |
+ // GroupNames holds all the groups directly bound to the role |
|
| 47 |
+ GroupNames []string `json:"groupNames"` |
|
| 48 |
+ |
|
| 49 |
+ // Since Policy is a singleton, this is sufficient knowledge to locate a role |
|
| 50 |
+ // RoleRefs can only reference the current namespace and the global namespace |
|
| 51 |
+ // If the RoleRef cannot be resolved, the Authorizer must return an error. |
|
| 52 |
+ RoleRef kapi.ObjectReference `json:"roleRef"` |
|
| 53 |
+} |
|
| 54 |
+ |
|
| 55 |
+// Policy is a object that holds all the Roles for a particular namespace. There is at most |
|
| 56 |
+// one Policy document per namespace. |
|
| 57 |
+type Policy struct {
|
|
| 58 |
+ kapi.TypeMeta `json:",inline"` |
|
| 59 |
+ kapi.ObjectMeta `json:"metadata,omitempty"` |
|
| 60 |
+ |
|
| 61 |
+ // LastModified is the last time that any part of the Policy was created, updated, or deleted |
|
| 62 |
+ LastModified kutil.Time `json:"lastModified"` |
|
| 63 |
+ |
|
| 64 |
+ // Roles holds all the Roles held by this Policy, mapped by Role.Name |
|
| 65 |
+ Roles []NamedRole `json:"roles"` |
|
| 66 |
+} |
|
| 67 |
+ |
|
| 68 |
+// PolicyBinding is a object that holds all the RoleBindings for a particular namespace. There is |
|
| 69 |
+// one PolicyBinding document per referenced Policy namespace |
|
| 70 |
+type PolicyBinding struct {
|
|
| 71 |
+ kapi.TypeMeta `json:",inline"` |
|
| 72 |
+ kapi.ObjectMeta `json:"metadata,omitempty"` |
|
| 73 |
+ |
|
| 74 |
+ // LastModified is the last time that any part of the PolicyBinding was created, updated, or deleted |
|
| 75 |
+ LastModified kutil.Time `json:"lastModified"` |
|
| 76 |
+ |
|
| 77 |
+ // PolicyRef is a reference to the Policy that contains all the Roles that this PolicyBinding's RoleBindings may reference |
|
| 78 |
+ PolicyRef kapi.ObjectReference `json:"policyRef"` |
|
| 79 |
+ // RoleBindings holds all the RoleBindings held by this PolicyBinding, mapped by RoleBinding.Name |
|
| 80 |
+ RoleBindings []NamedRoleBinding `json:"roleBindings"` |
|
| 81 |
+} |
|
| 82 |
+ |
|
| 83 |
+type NamedRole struct {
|
|
| 84 |
+ Name string `json:"name"` |
|
| 85 |
+ Role Role `json:"role"` |
|
| 86 |
+} |
|
| 87 |
+ |
|
| 88 |
+type NamedRoleBinding struct {
|
|
| 89 |
+ Name string `json:"name"` |
|
| 90 |
+ RoleBinding RoleBinding `json:"roleBinding"` |
|
| 91 |
+} |
|
| 92 |
+ |
|
| 93 |
+// PolicyList is a collection of Policies |
|
| 94 |
+type PolicyList struct {
|
|
| 95 |
+ kapi.TypeMeta `json:",inline"` |
|
| 96 |
+ kapi.ListMeta `json:"metadata,omitempty"` |
|
| 97 |
+ Items []Policy `json:"items"` |
|
| 98 |
+} |
|
| 99 |
+ |
|
| 100 |
+// PolicyBindingList is a collection of PolicyBindings |
|
| 101 |
+type PolicyBindingList struct {
|
|
| 102 |
+ kapi.TypeMeta `json:",inline"` |
|
| 103 |
+ kapi.ListMeta `json:"metadata,omitempty"` |
|
| 104 |
+ Items []PolicyBinding `json:"items"` |
|
| 105 |
+} |
| 0 | 106 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,55 @@ |
| 0 |
+package validation |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ errs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" |
|
| 4 |
+ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" |
|
| 5 |
+ "github.com/GoogleCloudPlatform/kubernetes/pkg/util" |
|
| 6 |
+ |
|
| 7 |
+ authorizationapi "github.com/openshift/origin/pkg/authorization/api" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+// ValidatePolicyBinding tests required fields for a PolicyBinding. |
|
| 11 |
+func ValidatePolicyBinding(policyBinding *authorizationapi.PolicyBinding) errs.ValidationErrorList {
|
|
| 12 |
+ allErrs := errs.ValidationErrorList{}
|
|
| 13 |
+ |
|
| 14 |
+ if len(policyBinding.Name) == 0 {
|
|
| 15 |
+ allErrs = append(allErrs, errs.NewFieldRequired("name", policyBinding.Name))
|
|
| 16 |
+ } |
|
| 17 |
+ |
|
| 18 |
+ if len(policyBinding.PolicyRef.Namespace) == 0 {
|
|
| 19 |
+ allErrs = append(allErrs, errs.NewFieldRequired("policyRef.Namespace", policyBinding.PolicyRef.Namespace))
|
|
| 20 |
+ } |
|
| 21 |
+ |
|
| 22 |
+ allErrs = append(allErrs, validation.ValidateLabels(policyBinding.Labels, "labels")...) |
|
| 23 |
+ return allErrs |
|
| 24 |
+} |
|
| 25 |
+ |
|
| 26 |
+// ValidateRole tests required fields for a Role. |
|
| 27 |
+func ValidateRole(role *authorizationapi.Role) errs.ValidationErrorList {
|
|
| 28 |
+ allErrs := errs.ValidationErrorList{}
|
|
| 29 |
+ |
|
| 30 |
+ if len(role.Name) == 0 {
|
|
| 31 |
+ allErrs = append(allErrs, errs.NewFieldRequired("name", role.Name))
|
|
| 32 |
+ } |
|
| 33 |
+ |
|
| 34 |
+ allErrs = append(allErrs, validation.ValidateLabels(role.Labels, "labels")...) |
|
| 35 |
+ return allErrs |
|
| 36 |
+} |
|
| 37 |
+ |
|
| 38 |
+// ValidateRoleBinding tests required fields for a RoleBinding. |
|
| 39 |
+func ValidateRoleBinding(roleBinding *authorizationapi.RoleBinding) errs.ValidationErrorList {
|
|
| 40 |
+ allErrs := errs.ValidationErrorList{}
|
|
| 41 |
+ |
|
| 42 |
+ if len(roleBinding.Name) == 0 {
|
|
| 43 |
+ allErrs = append(allErrs, errs.NewFieldRequired("name", roleBinding.Name))
|
|
| 44 |
+ } |
|
| 45 |
+ |
|
| 46 |
+ if len(roleBinding.RoleRef.Namespace) == 0 {
|
|
| 47 |
+ allErrs = append(allErrs, errs.NewFieldRequired("roleRef.namespace", roleBinding.RoleRef.Namespace))
|
|
| 48 |
+ } else if !util.IsDNSSubdomain(roleBinding.RoleRef.Namespace) {
|
|
| 49 |
+ allErrs = append(allErrs, errs.NewFieldInvalid("roleRef.namespace", roleBinding.RoleRef.Namespace, "roleRef.namespace must be a valid subdomain"))
|
|
| 50 |
+ } |
|
| 51 |
+ |
|
| 52 |
+ allErrs = append(allErrs, validation.ValidateLabels(roleBinding.Labels, "labels")...) |
|
| 53 |
+ return allErrs |
|
| 54 |
+} |
| 0 | 55 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,65 @@ |
| 0 |
+package validation |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "testing" |
|
| 4 |
+ |
|
| 5 |
+ kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api" |
|
| 6 |
+ |
|
| 7 |
+ authorizationapi "github.com/openshift/origin/pkg/authorization/api" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+func TestRoleValidationSuccess(t *testing.T) {
|
|
| 11 |
+ role := &authorizationapi.Role{}
|
|
| 12 |
+ role.Name = "my-name" |
|
| 13 |
+ role.Namespace = kapi.NamespaceDefault |
|
| 14 |
+ |
|
| 15 |
+ if result := ValidateRole(role); len(result) > 0 {
|
|
| 16 |
+ t.Errorf("Unexpected validation error returned %v", result)
|
|
| 17 |
+ } |
|
| 18 |
+} |
|
| 19 |
+ |
|
| 20 |
+func TestRoleValidationFailure(t *testing.T) {
|
|
| 21 |
+ role := &authorizationapi.Role{}
|
|
| 22 |
+ role.Namespace = kapi.NamespaceDefault |
|
| 23 |
+ if result := ValidateRole(role); len(result) != 1 {
|
|
| 24 |
+ t.Errorf("Unexpected validation result: %v", result)
|
|
| 25 |
+ } |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+func TestRoleBindingValidationSuccess(t *testing.T) {
|
|
| 29 |
+ roleBinding := &authorizationapi.RoleBinding{}
|
|
| 30 |
+ roleBinding.Name = "my-name" |
|
| 31 |
+ roleBinding.Namespace = kapi.NamespaceDefault |
|
| 32 |
+ roleBinding.RoleRef.Namespace = kapi.NamespaceDefault |
|
| 33 |
+ |
|
| 34 |
+ if result := ValidateRoleBinding(roleBinding); len(result) > 0 {
|
|
| 35 |
+ t.Errorf("Unexpected validation error returned %v", result)
|
|
| 36 |
+ } |
|
| 37 |
+} |
|
| 38 |
+ |
|
| 39 |
+func TestRoleBindingValidationFailure(t *testing.T) {
|
|
| 40 |
+ roleBinding := &authorizationapi.RoleBinding{}
|
|
| 41 |
+ roleBinding.Namespace = kapi.NamespaceDefault |
|
| 42 |
+ if result := ValidateRoleBinding(roleBinding); len(result) != 2 {
|
|
| 43 |
+ t.Errorf("Unexpected validation result: %v", result)
|
|
| 44 |
+ } |
|
| 45 |
+} |
|
| 46 |
+ |
|
| 47 |
+func TestPolicyBindingValidationSuccess(t *testing.T) {
|
|
| 48 |
+ policyBinding := &authorizationapi.PolicyBinding{}
|
|
| 49 |
+ policyBinding.Name = "my-name" |
|
| 50 |
+ policyBinding.Namespace = kapi.NamespaceDefault |
|
| 51 |
+ policyBinding.PolicyRef.Namespace = "my-name" |
|
| 52 |
+ |
|
| 53 |
+ if result := ValidatePolicyBinding(policyBinding); len(result) > 0 {
|
|
| 54 |
+ t.Errorf("Unexpected validation error returned %v", result)
|
|
| 55 |
+ } |
|
| 56 |
+} |
|
| 57 |
+ |
|
| 58 |
+func TestPolicyBindingValidationFailure(t *testing.T) {
|
|
| 59 |
+ policyBinding := &authorizationapi.PolicyBinding{}
|
|
| 60 |
+ policyBinding.Namespace = kapi.NamespaceDefault |
|
| 61 |
+ if result := ValidatePolicyBinding(policyBinding); len(result) != 2 {
|
|
| 62 |
+ t.Errorf("Unexpected validation result: %v", result)
|
|
| 63 |
+ } |
|
| 64 |
+} |