Add glide.yaml and vendor deps

This commit is contained in:
Dalton Hubble 2016-12-03 22:43:32 -08:00
parent db918f12ad
commit 5b3d5e81bd
18880 changed files with 5166045 additions and 1 deletions

31
vendor/k8s.io/kubernetes/pkg/apis/rbac/BUILD generated vendored Normal file
View file

@ -0,0 +1,31 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"helpers.go",
"register.go",
"types.go",
"zz_generated.deepcopy.go",
],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/apis/meta/v1:go_default_library",
"//pkg/conversion:go_default_library",
"//pkg/runtime:go_default_library",
"//pkg/runtime/schema:go_default_library",
"//pkg/watch/versioned:go_default_library",
],
)

16
vendor/k8s.io/kubernetes/pkg/apis/rbac/OWNERS generated vendored Executable file
View file

@ -0,0 +1,16 @@
reviewers:
- thockin
- lavalamp
- smarterclayton
- deads2k
- sttts
- ncdc
- timothysc
- dims
- krousey
- mml
- mbohlool
- david-mcmahon
- ericchiang
- lixiaobing10051267
- jianhuiz

21
vendor/k8s.io/kubernetes/pkg/apis/rbac/doc.go generated vendored Normal file
View file

@ -0,0 +1,21 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:deepcopy-gen=package,register
// +k8s:openapi-gen=true
// +groupName=rbac.authorization.k8s.io
package rbac // import "k8s.io/kubernetes/pkg/apis/rbac"

249
vendor/k8s.io/kubernetes/pkg/apis/rbac/helpers.go generated vendored Normal file
View file

@ -0,0 +1,249 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rbac
import (
"fmt"
"strings"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/runtime/schema"
)
func RoleRefGroupKind(roleRef RoleRef) schema.GroupKind {
return schema.GroupKind{Group: roleRef.APIGroup, Kind: roleRef.Kind}
}
func VerbMatches(rule PolicyRule, requestedVerb string) bool {
for _, ruleVerb := range rule.Verbs {
if ruleVerb == VerbAll {
return true
}
if ruleVerb == requestedVerb {
return true
}
}
return false
}
func APIGroupMatches(rule PolicyRule, requestedGroup string) bool {
for _, ruleGroup := range rule.APIGroups {
if ruleGroup == APIGroupAll {
return true
}
if ruleGroup == requestedGroup {
return true
}
}
return false
}
func ResourceMatches(rule PolicyRule, requestedResource string) bool {
for _, ruleResource := range rule.Resources {
if ruleResource == ResourceAll {
return true
}
if ruleResource == requestedResource {
return true
}
}
return false
}
func ResourceNameMatches(rule PolicyRule, requestedName string) bool {
if len(rule.ResourceNames) == 0 {
return true
}
for _, ruleName := range rule.ResourceNames {
if ruleName == requestedName {
return true
}
}
return false
}
func NonResourceURLMatches(rule PolicyRule, requestedURL string) bool {
for _, ruleURL := range rule.NonResourceURLs {
if ruleURL == NonResourceAll {
return true
}
if ruleURL == requestedURL {
return true
}
if strings.HasSuffix(ruleURL, "*") && strings.HasPrefix(requestedURL, strings.TrimRight(ruleURL, "*")) {
return true
}
}
return false
}
// subjectsStrings returns users, groups, serviceaccounts, unknown for display purposes.
func SubjectsStrings(subjects []Subject) ([]string, []string, []string, []string) {
users := []string{}
groups := []string{}
sas := []string{}
others := []string{}
for _, subject := range subjects {
switch subject.Kind {
case ServiceAccountKind:
sas = append(sas, fmt.Sprintf("%s/%s", subject.Namespace, subject.Name))
case UserKind:
users = append(users, subject.Name)
case GroupKind:
groups = append(groups, subject.Name)
default:
others = append(others, fmt.Sprintf("%s/%s/%s", subject.Kind, subject.Namespace, subject.Name))
}
}
return users, groups, sas, others
}
// +k8s:deepcopy-gen=false
// PolicyRuleBuilder let's us attach methods. A no-no for API types.
// We use it to construct rules in code. It's more compact than trying to write them
// out in a literal and allows us to perform some basic checking during construction
type PolicyRuleBuilder struct {
PolicyRule PolicyRule
}
func NewRule(verbs ...string) *PolicyRuleBuilder {
return &PolicyRuleBuilder{
PolicyRule: PolicyRule{Verbs: verbs},
}
}
func (r *PolicyRuleBuilder) Groups(groups ...string) *PolicyRuleBuilder {
r.PolicyRule.APIGroups = append(r.PolicyRule.APIGroups, groups...)
return r
}
func (r *PolicyRuleBuilder) Resources(resources ...string) *PolicyRuleBuilder {
r.PolicyRule.Resources = append(r.PolicyRule.Resources, resources...)
return r
}
func (r *PolicyRuleBuilder) Names(names ...string) *PolicyRuleBuilder {
r.PolicyRule.ResourceNames = append(r.PolicyRule.ResourceNames, names...)
return r
}
func (r *PolicyRuleBuilder) URLs(urls ...string) *PolicyRuleBuilder {
r.PolicyRule.NonResourceURLs = append(r.PolicyRule.NonResourceURLs, urls...)
return r
}
func (r *PolicyRuleBuilder) RuleOrDie() PolicyRule {
ret, err := r.Rule()
if err != nil {
panic(err)
}
return ret
}
func (r *PolicyRuleBuilder) Rule() (PolicyRule, error) {
if len(r.PolicyRule.Verbs) == 0 {
return PolicyRule{}, fmt.Errorf("verbs are required: %#v", r.PolicyRule)
}
switch {
case len(r.PolicyRule.NonResourceURLs) > 0:
if len(r.PolicyRule.APIGroups) != 0 || len(r.PolicyRule.Resources) != 0 || len(r.PolicyRule.ResourceNames) != 0 {
return PolicyRule{}, fmt.Errorf("non-resource rule may not have apiGroups, resources, or resourceNames: %#v", r.PolicyRule)
}
case len(r.PolicyRule.Resources) > 0:
if len(r.PolicyRule.NonResourceURLs) != 0 {
return PolicyRule{}, fmt.Errorf("resource rule may not have nonResourceURLs: %#v", r.PolicyRule)
}
if len(r.PolicyRule.APIGroups) == 0 {
// this a common bug
return PolicyRule{}, fmt.Errorf("resource rule must have apiGroups: %#v", r.PolicyRule)
}
default:
return PolicyRule{}, fmt.Errorf("a rule must have either nonResourceURLs or resources: %#v", r.PolicyRule)
}
return r.PolicyRule, nil
}
// +k8s:deepcopy-gen=false
// ClusterRoleBindingBuilder let's us attach methods. A no-no for API types.
// We use it to construct bindings in code. It's more compact than trying to write them
// out in a literal.
type ClusterRoleBindingBuilder struct {
ClusterRoleBinding ClusterRoleBinding
}
func NewClusterBinding(clusterRoleName string) *ClusterRoleBindingBuilder {
return &ClusterRoleBindingBuilder{
ClusterRoleBinding: ClusterRoleBinding{
ObjectMeta: api.ObjectMeta{Name: clusterRoleName},
RoleRef: RoleRef{
APIGroup: GroupName,
Kind: "ClusterRole",
Name: clusterRoleName,
},
},
}
}
func (r *ClusterRoleBindingBuilder) Groups(groups ...string) *ClusterRoleBindingBuilder {
for _, group := range groups {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: GroupKind, Name: group})
}
return r
}
func (r *ClusterRoleBindingBuilder) Users(users ...string) *ClusterRoleBindingBuilder {
for _, user := range users {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: UserKind, Name: user})
}
return r
}
func (r *ClusterRoleBindingBuilder) SAs(namespace string, serviceAccountNames ...string) *ClusterRoleBindingBuilder {
for _, saName := range serviceAccountNames {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: ServiceAccountKind, Namespace: namespace, Name: saName})
}
return r
}
func (r *ClusterRoleBindingBuilder) BindingOrDie() ClusterRoleBinding {
ret, err := r.Binding()
if err != nil {
panic(err)
}
return ret
}
func (r *ClusterRoleBindingBuilder) Binding() (ClusterRoleBinding, error) {
if len(r.ClusterRoleBinding.Subjects) == 0 {
return ClusterRoleBinding{}, fmt.Errorf("subjects are required: %#v", r.ClusterRoleBinding)
}
return r.ClusterRoleBinding, nil
}

23
vendor/k8s.io/kubernetes/pkg/apis/rbac/install/BUILD generated vendored Normal file
View file

@ -0,0 +1,23 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = ["install.go"],
tags = ["automanaged"],
deps = [
"//pkg/apimachinery/announced:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/apis/rbac/v1alpha1:go_default_library",
"//pkg/util/sets:go_default_library",
],
)

View file

@ -0,0 +1,43 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package install installs the batch API group, making it available as
// an option to all of the API encoding/decoding machinery.
package install
import (
"k8s.io/kubernetes/pkg/apimachinery/announced"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/v1alpha1"
"k8s.io/kubernetes/pkg/util/sets"
)
func init() {
if err := announced.NewGroupMetaFactory(
&announced.GroupMetaFactoryArgs{
GroupName: rbac.GroupName,
VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version},
ImportPrefix: "k8s.io/kubernetes/pkg/apis/rbac",
RootScopedKinds: sets.NewString("ClusterRole", "ClusterRoleBinding"),
AddInternalObjectsToScheme: rbac.AddToScheme,
},
announced.VersionToSchemeFunc{
v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme,
},
).Announce().RegisterAndEnable(); err != nil {
panic(err)
}
}

66
vendor/k8s.io/kubernetes/pkg/apis/rbac/register.go generated vendored Normal file
View file

@ -0,0 +1,66 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rbac
import (
"k8s.io/kubernetes/pkg/api"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/watch/versioned"
)
const GroupName = "rbac.authorization.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme
)
// Adds the list of known types to api.Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&Role{},
&RoleBinding{},
&RoleBindingList{},
&RoleList{},
&ClusterRole{},
&ClusterRoleBinding{},
&ClusterRoleBindingList{},
&ClusterRoleList{},
&api.ListOptions{},
&api.DeleteOptions{},
&metav1.ExportOptions{},
)
versioned.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

191
vendor/k8s.io/kubernetes/pkg/apis/rbac/types.go generated vendored Normal file
View file

@ -0,0 +1,191 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rbac
import (
"k8s.io/kubernetes/pkg/api"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/runtime"
)
// Authorization is calculated against
// 1. evaluation of ClusterRoleBindings - short circuit on match
// 2. evaluation of RoleBindings in the namespace requested - short circuit on match
// 3. deny by default
const (
APIGroupAll = "*"
ResourceAll = "*"
VerbAll = "*"
NonResourceAll = "*"
GroupKind = "Group"
ServiceAccountKind = "ServiceAccount"
UserKind = "User"
UserAll = "*"
)
// PolicyRule holds information that describes a policy rule, but does not contain information
// about who the rule applies to or which namespace the rule applies to.
type PolicyRule struct {
// Verbs is a list of Verbs that apply to ALL the ResourceKinds and AttributeRestrictions contained in this rule. VerbAll represents all kinds.
Verbs []string
// AttributeRestrictions will vary depending on what the Authorizer/AuthorizationAttributeBuilder pair supports.
// If the Authorizer does not recognize how to handle the AttributeRestrictions, the Authorizer should report an error.
AttributeRestrictions runtime.Object
// APIGroups is the name of the APIGroup that contains the resources.
// If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed.
APIGroups []string
// Resources is a list of resources this rule applies to. ResourceAll represents all resources.
Resources []string
// ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
ResourceNames []string
// NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path
// If an action is not a resource API request, then the URL is split on '/' and is checked against the NonResourceURLs to look for a match.
// Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding.
// Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both.
NonResourceURLs []string
}
// Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference,
// or a value for non-objects such as user and group names.
type Subject struct {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
Kind string
// APIVersion holds the API group and version of the referenced object. For non-object references such as "Group" and "User" this is
// expected to be API version of this API group. For example, "rbac/v1alpha1".
APIVersion string
// Name of the object being referenced.
Name string
// Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty
// the Authorizer should report an error.
Namespace string
}
// RoleRef contains information that points to the role being used
type RoleRef struct {
// APIGroup is the group for the resource being referenced
APIGroup string
// Kind is the type of resource being referenced
Kind string
// Name is the name of resource being referenced
Name string
}
// +genclient=true
// Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding.
type Role struct {
metav1.TypeMeta
// Standard object's metadata.
api.ObjectMeta
// Rules holds all the PolicyRules for this Role
Rules []PolicyRule
}
// +genclient=true
// RoleBinding references a role, but does not contain it. It can reference a Role in the same namespace or a ClusterRole in the global namespace.
// It adds who information via Subjects and namespace information by which namespace it exists in. RoleBindings in a given
// namespace only have effect in that namespace.
type RoleBinding struct {
metav1.TypeMeta
api.ObjectMeta
// Subjects holds references to the objects the role applies to.
Subjects []Subject
// RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace.
// If the RoleRef cannot be resolved, the Authorizer must return an error.
RoleRef RoleRef
}
// RoleBindingList is a collection of RoleBindings
type RoleBindingList struct {
metav1.TypeMeta
// Standard object's metadata.
metav1.ListMeta
// Items is a list of roleBindings
Items []RoleBinding
}
// RoleList is a collection of Roles
type RoleList struct {
metav1.TypeMeta
// Standard object's metadata.
metav1.ListMeta
// Items is a list of roles
Items []Role
}
// +genclient=true
// +nonNamespaced=true
// ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding.
type ClusterRole struct {
metav1.TypeMeta
// Standard object's metadata.
api.ObjectMeta
// Rules holds all the PolicyRules for this ClusterRole
Rules []PolicyRule
}
// +genclient=true
// +nonNamespaced=true
// ClusterRoleBinding references a ClusterRole, but not contain it. It can reference a ClusterRole in the global namespace,
// and adds who information via Subject.
type ClusterRoleBinding struct {
metav1.TypeMeta
// Standard object's metadata.
api.ObjectMeta
// Subjects holds references to the objects the role applies to.
Subjects []Subject
// RoleRef can only reference a ClusterRole in the global namespace.
// If the RoleRef cannot be resolved, the Authorizer must return an error.
RoleRef RoleRef
}
// ClusterRoleBindingList is a collection of ClusterRoleBindings
type ClusterRoleBindingList struct {
metav1.TypeMeta
// Standard object's metadata.
metav1.ListMeta
// Items is a list of ClusterRoleBindings
Items []ClusterRoleBinding
}
// ClusterRoleList is a collection of ClusterRoles
type ClusterRoleList struct {
metav1.TypeMeta
// Standard object's metadata.
metav1.ListMeta
// Items is a list of ClusterRoles
Items []ClusterRole
}

41
vendor/k8s.io/kubernetes/pkg/apis/rbac/v1alpha1/BUILD generated vendored Normal file
View file

@ -0,0 +1,41 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = [
"defaults.go",
"doc.go",
"generated.pb.go",
"helpers.go",
"register.go",
"types.generated.go",
"types.go",
"types_swagger_doc_generated.go",
"zz_generated.conversion.go",
"zz_generated.deepcopy.go",
"zz_generated.defaults.go",
],
tags = ["automanaged"],
deps = [
"//pkg/api/v1:go_default_library",
"//pkg/apis/meta/v1:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/conversion:go_default_library",
"//pkg/runtime:go_default_library",
"//pkg/runtime/schema:go_default_library",
"//pkg/types:go_default_library",
"//pkg/watch/versioned:go_default_library",
"//vendor:github.com/gogo/protobuf/proto",
"//vendor:github.com/ugorji/go/codec",
],
)

View file

@ -0,0 +1,40 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
"k8s.io/kubernetes/pkg/runtime"
)
func addDefaultingFuncs(scheme *runtime.Scheme) error {
RegisterDefaults(scheme)
return scheme.AddDefaultingFuncs(
SetDefaults_ClusterRoleBinding,
SetDefaults_RoleBinding,
)
}
func SetDefaults_ClusterRoleBinding(obj *ClusterRoleBinding) {
if len(obj.RoleRef.APIGroup) == 0 {
obj.RoleRef.APIGroup = GroupName
}
}
func SetDefaults_RoleBinding(obj *RoleBinding) {
if len(obj.RoleRef.APIGroup) == 0 {
obj.RoleRef.APIGroup = GroupName
}
}

23
vendor/k8s.io/kubernetes/pkg/apis/rbac/v1alpha1/doc.go generated vendored Normal file
View file

@ -0,0 +1,23 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=k8s.io/kubernetes/pkg/apis/rbac
// +k8s:openapi-gen=true
// +k8s:defaulter-gen=TypeMeta
// +groupName=rbac.authorization.k8s.io
package v1alpha1 // import "k8s.io/kubernetes/pkg/apis/rbac/v1alpha1"

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,204 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This file was autogenerated by go-to-protobuf. Do not edit it manually!
syntax = 'proto2';
package k8s.io.kubernetes.pkg.apis.rbac.v1alpha1;
import "k8s.io/kubernetes/pkg/api/resource/generated.proto";
import "k8s.io/kubernetes/pkg/api/v1/generated.proto";
import "k8s.io/kubernetes/pkg/apis/meta/v1/generated.proto";
import "k8s.io/kubernetes/pkg/runtime/generated.proto";
import "k8s.io/kubernetes/pkg/runtime/schema/generated.proto";
import "k8s.io/kubernetes/pkg/util/intstr/generated.proto";
// Package-wide variables from generator "generated".
option go_package = "v1alpha1";
// ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding.
message ClusterRole {
// Standard object's metadata.
// +optional
optional k8s.io.kubernetes.pkg.api.v1.ObjectMeta metadata = 1;
// Rules holds all the PolicyRules for this ClusterRole
repeated PolicyRule rules = 2;
}
// ClusterRoleBinding references a ClusterRole, but not contain it. It can reference a ClusterRole in the global namespace,
// and adds who information via Subject.
message ClusterRoleBinding {
// Standard object's metadata.
// +optional
optional k8s.io.kubernetes.pkg.api.v1.ObjectMeta metadata = 1;
// Subjects holds references to the objects the role applies to.
repeated Subject subjects = 2;
// RoleRef can only reference a ClusterRole in the global namespace.
// If the RoleRef cannot be resolved, the Authorizer must return an error.
optional RoleRef roleRef = 3;
}
// +k8s:deepcopy-gen=false
// ClusterRoleBindingBuilder let's us attach methods. A no-no for API types.
// We use it to construct bindings in code. It's more compact than trying to write them
// out in a literal.
message ClusterRoleBindingBuilder {
optional ClusterRoleBinding clusterRoleBinding = 1;
}
// ClusterRoleBindingList is a collection of ClusterRoleBindings
message ClusterRoleBindingList {
// Standard object's metadata.
// +optional
optional k8s.io.kubernetes.pkg.apis.meta.v1.ListMeta metadata = 1;
// Items is a list of ClusterRoleBindings
repeated ClusterRoleBinding items = 2;
}
// ClusterRoleList is a collection of ClusterRoles
message ClusterRoleList {
// Standard object's metadata.
// +optional
optional k8s.io.kubernetes.pkg.apis.meta.v1.ListMeta metadata = 1;
// Items is a list of ClusterRoles
repeated ClusterRole items = 2;
}
// PolicyRule holds information that describes a policy rule, but does not contain information
// about who the rule applies to or which namespace the rule applies to.
message PolicyRule {
// Verbs is a list of Verbs that apply to ALL the ResourceKinds and AttributeRestrictions contained in this rule. VerbAll represents all kinds.
repeated string verbs = 1;
// AttributeRestrictions will vary depending on what the Authorizer/AuthorizationAttributeBuilder pair supports.
// If the Authorizer does not recognize how to handle the AttributeRestrictions, the Authorizer should report an error.
// +optional
optional k8s.io.kubernetes.pkg.runtime.RawExtension attributeRestrictions = 2;
// APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of
// the enumerated resources in any API group will be allowed.
// +optional
repeated string apiGroups = 3;
// Resources is a list of resources this rule applies to. ResourceAll represents all resources.
// +optional
repeated string resources = 4;
// ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
// +optional
repeated string resourceNames = 5;
// NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path
// This name is intentionally different than the internal type so that the DefaultConvert works nicely and because the ordering may be different.
// Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding.
// Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both.
// +optional
repeated string nonResourceURLs = 6;
}
// +k8s:deepcopy-gen=false
// PolicyRuleBuilder let's us attach methods. A no-no for API types.
// We use it to construct rules in code. It's more compact than trying to write them
// out in a literal and allows us to perform some basic checking during construction
message PolicyRuleBuilder {
optional PolicyRule policyRule = 1;
}
// Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding.
message Role {
// Standard object's metadata.
// +optional
optional k8s.io.kubernetes.pkg.api.v1.ObjectMeta metadata = 1;
// Rules holds all the PolicyRules for this Role
repeated PolicyRule rules = 2;
}
// RoleBinding references a role, but does not contain it. It can reference a Role in the same namespace or a ClusterRole in the global namespace.
// It adds who information via Subjects and namespace information by which namespace it exists in. RoleBindings in a given
// namespace only have effect in that namespace.
message RoleBinding {
// Standard object's metadata.
// +optional
optional k8s.io.kubernetes.pkg.api.v1.ObjectMeta metadata = 1;
// Subjects holds references to the objects the role applies to.
repeated Subject subjects = 2;
// RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace.
// If the RoleRef cannot be resolved, the Authorizer must return an error.
optional RoleRef roleRef = 3;
}
// RoleBindingList is a collection of RoleBindings
message RoleBindingList {
// Standard object's metadata.
// +optional
optional k8s.io.kubernetes.pkg.apis.meta.v1.ListMeta metadata = 1;
// Items is a list of RoleBindings
repeated RoleBinding items = 2;
}
// RoleList is a collection of Roles
message RoleList {
// Standard object's metadata.
// +optional
optional k8s.io.kubernetes.pkg.apis.meta.v1.ListMeta metadata = 1;
// Items is a list of Roles
repeated Role items = 2;
}
// RoleRef contains information that points to the role being used
message RoleRef {
// APIGroup is the group for the resource being referenced
optional string apiGroup = 1;
// Kind is the type of resource being referenced
optional string kind = 2;
// Name is the name of resource being referenced
optional string name = 3;
}
// Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference,
// or a value for non-objects such as user and group names.
message Subject {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
optional string kind = 1;
// APIVersion holds the API group and version of the referenced object.
// +optional
optional string apiVersion = 2;
// Name of the object being referenced.
optional string name = 3;
// Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty
// the Authorizer should report an error.
// +optional
optional string namespace = 4;
}

View file

@ -0,0 +1,148 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
"fmt"
"k8s.io/kubernetes/pkg/api/v1"
)
// +k8s:deepcopy-gen=false
// PolicyRuleBuilder let's us attach methods. A no-no for API types.
// We use it to construct rules in code. It's more compact than trying to write them
// out in a literal and allows us to perform some basic checking during construction
type PolicyRuleBuilder struct {
PolicyRule PolicyRule `protobuf:"bytes,1,opt,name=policyRule"`
}
func NewRule(verbs ...string) *PolicyRuleBuilder {
return &PolicyRuleBuilder{
PolicyRule: PolicyRule{Verbs: verbs},
}
}
func (r *PolicyRuleBuilder) Groups(groups ...string) *PolicyRuleBuilder {
r.PolicyRule.APIGroups = append(r.PolicyRule.APIGroups, groups...)
return r
}
func (r *PolicyRuleBuilder) Resources(resources ...string) *PolicyRuleBuilder {
r.PolicyRule.Resources = append(r.PolicyRule.Resources, resources...)
return r
}
func (r *PolicyRuleBuilder) Names(names ...string) *PolicyRuleBuilder {
r.PolicyRule.ResourceNames = append(r.PolicyRule.ResourceNames, names...)
return r
}
func (r *PolicyRuleBuilder) URLs(urls ...string) *PolicyRuleBuilder {
r.PolicyRule.NonResourceURLs = append(r.PolicyRule.NonResourceURLs, urls...)
return r
}
func (r *PolicyRuleBuilder) RuleOrDie() PolicyRule {
ret, err := r.Rule()
if err != nil {
panic(err)
}
return ret
}
func (r *PolicyRuleBuilder) Rule() (PolicyRule, error) {
if len(r.PolicyRule.Verbs) == 0 {
return PolicyRule{}, fmt.Errorf("verbs are required: %#v", r.PolicyRule)
}
switch {
case len(r.PolicyRule.NonResourceURLs) > 0:
if len(r.PolicyRule.APIGroups) != 0 || len(r.PolicyRule.Resources) != 0 || len(r.PolicyRule.ResourceNames) != 0 {
return PolicyRule{}, fmt.Errorf("non-resource rule may not have apiGroups, resources, or resourceNames: %#v", r.PolicyRule)
}
case len(r.PolicyRule.Resources) > 0:
if len(r.PolicyRule.NonResourceURLs) != 0 {
return PolicyRule{}, fmt.Errorf("resource rule may not have nonResourceURLs: %#v", r.PolicyRule)
}
if len(r.PolicyRule.APIGroups) == 0 {
// this a common bug
return PolicyRule{}, fmt.Errorf("resource rule must have apiGroups: %#v", r.PolicyRule)
}
default:
return PolicyRule{}, fmt.Errorf("a rule must have either nonResourceURLs or resources: %#v", r.PolicyRule)
}
return r.PolicyRule, nil
}
// +k8s:deepcopy-gen=false
// ClusterRoleBindingBuilder let's us attach methods. A no-no for API types.
// We use it to construct bindings in code. It's more compact than trying to write them
// out in a literal.
type ClusterRoleBindingBuilder struct {
ClusterRoleBinding ClusterRoleBinding `protobuf:"bytes,1,opt,name=clusterRoleBinding"`
}
func NewClusterBinding(clusterRoleName string) *ClusterRoleBindingBuilder {
return &ClusterRoleBindingBuilder{
ClusterRoleBinding: ClusterRoleBinding{
ObjectMeta: v1.ObjectMeta{Name: clusterRoleName},
RoleRef: RoleRef{
APIGroup: GroupName,
Kind: "ClusterRole",
Name: clusterRoleName,
},
},
}
}
func (r *ClusterRoleBindingBuilder) Groups(groups ...string) *ClusterRoleBindingBuilder {
for _, group := range groups {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: GroupKind, Name: group})
}
return r
}
func (r *ClusterRoleBindingBuilder) Users(users ...string) *ClusterRoleBindingBuilder {
for _, user := range users {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: UserKind, Name: user})
}
return r
}
func (r *ClusterRoleBindingBuilder) SAs(namespace string, serviceAccountNames ...string) *ClusterRoleBindingBuilder {
for _, saName := range serviceAccountNames {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, Subject{Kind: ServiceAccountKind, Namespace: namespace, Name: saName})
}
return r
}
func (r *ClusterRoleBindingBuilder) BindingOrDie() ClusterRoleBinding {
ret, err := r.Binding()
if err != nil {
panic(err)
}
return ret
}
func (r *ClusterRoleBindingBuilder) Binding() (ClusterRoleBinding, error) {
if len(r.ClusterRoleBinding.Subjects) == 0 {
return ClusterRoleBinding{}, fmt.Errorf("subjects are required: %#v", r.ClusterRoleBinding)
}
return r.ClusterRoleBinding, nil
}

View file

@ -0,0 +1,61 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
"k8s.io/kubernetes/pkg/api/v1"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/watch/versioned"
)
const GroupName = "rbac.authorization.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes, addDefaultingFuncs)
AddToScheme = SchemeBuilder.AddToScheme
)
// Adds the list of known types to api.Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&Role{},
&RoleBinding{},
&RoleBindingList{},
&RoleList{},
&ClusterRole{},
&ClusterRoleBinding{},
&ClusterRoleBindingList{},
&ClusterRoleList{},
&v1.ListOptions{},
&v1.DeleteOptions{},
&metav1.ExportOptions{},
)
versioned.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,211 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
"k8s.io/kubernetes/pkg/api/v1"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/runtime"
)
// Authorization is calculated against
// 1. evaluation of ClusterRoleBindings - short circuit on match
// 2. evaluation of RoleBindings in the namespace requested - short circuit on match
// 3. deny by default
const (
APIGroupAll = "*"
ResourceAll = "*"
VerbAll = "*"
NonResourceAll = "*"
GroupKind = "Group"
ServiceAccountKind = "ServiceAccount"
UserKind = "User"
UserAll = "*"
)
// Authorization is calculated against
// 1. evaluation of ClusterRoleBindings - short circuit on match
// 2. evaluation of RoleBindings in the namespace requested - short circuit on match
// 3. deny by default
// PolicyRule holds information that describes a policy rule, but does not contain information
// about who the rule applies to or which namespace the rule applies to.
type PolicyRule struct {
// Verbs is a list of Verbs that apply to ALL the ResourceKinds and AttributeRestrictions contained in this rule. VerbAll represents all kinds.
Verbs []string `json:"verbs" protobuf:"bytes,1,rep,name=verbs"`
// AttributeRestrictions will vary depending on what the Authorizer/AuthorizationAttributeBuilder pair supports.
// If the Authorizer does not recognize how to handle the AttributeRestrictions, the Authorizer should report an error.
// +optional
AttributeRestrictions runtime.RawExtension `json:"attributeRestrictions,omitempty" protobuf:"bytes,2,opt,name=attributeRestrictions"`
// APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of
// the enumerated resources in any API group will be allowed.
// +optional
APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,3,rep,name=apiGroups"`
// Resources is a list of resources this rule applies to. ResourceAll represents all resources.
// +optional
Resources []string `json:"resources,omitempty" protobuf:"bytes,4,rep,name=resources"`
// ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
// +optional
ResourceNames []string `json:"resourceNames,omitempty" protobuf:"bytes,5,rep,name=resourceNames"`
// NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path
// This name is intentionally different than the internal type so that the DefaultConvert works nicely and because the ordering may be different.
// Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding.
// Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both.
// +optional
NonResourceURLs []string `json:"nonResourceURLs,omitempty" protobuf:"bytes,6,rep,name=nonResourceURLs"`
}
// Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference,
// or a value for non-objects such as user and group names.
type Subject struct {
// Kind of object being referenced. Values defined by this API group are "User", "Group", and "ServiceAccount".
// If the Authorizer does not recognized the kind value, the Authorizer should report an error.
Kind string `json:"kind" protobuf:"bytes,1,opt,name=kind"`
// APIVersion holds the API group and version of the referenced object.
// +optional
APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt.name=apiVersion"`
// Name of the object being referenced.
Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
// Namespace of the referenced object. If the object kind is non-namespace, such as "User" or "Group", and this value is not empty
// the Authorizer should report an error.
// +optional
Namespace string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"`
}
// RoleRef contains information that points to the role being used
type RoleRef struct {
// APIGroup is the group for the resource being referenced
APIGroup string `json:"apiGroup" protobuf:"bytes,1,opt,name=apiGroup"`
// Kind is the type of resource being referenced
Kind string `json:"kind" protobuf:"bytes,2,opt,name=kind"`
// Name is the name of resource being referenced
Name string `json:"name" protobuf:"bytes,3,opt,name=name"`
}
// +genclient=true
// Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding.
type Role struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
v1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Rules holds all the PolicyRules for this Role
Rules []PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"`
}
// +genclient=true
// RoleBinding references a role, but does not contain it. It can reference a Role in the same namespace or a ClusterRole in the global namespace.
// It adds who information via Subjects and namespace information by which namespace it exists in. RoleBindings in a given
// namespace only have effect in that namespace.
type RoleBinding struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
v1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Subjects holds references to the objects the role applies to.
Subjects []Subject `json:"subjects" protobuf:"bytes,2,rep,name=subjects"`
// RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace.
// If the RoleRef cannot be resolved, the Authorizer must return an error.
RoleRef RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"`
}
// RoleBindingList is a collection of RoleBindings
type RoleBindingList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Items is a list of RoleBindings
Items []RoleBinding `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// RoleList is a collection of Roles
type RoleList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Items is a list of Roles
Items []Role `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// +genclient=true
// +nonNamespaced=true
// ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding.
type ClusterRole struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
v1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Rules holds all the PolicyRules for this ClusterRole
Rules []PolicyRule `json:"rules" protobuf:"bytes,2,rep,name=rules"`
}
// +genclient=true
// +nonNamespaced=true
// ClusterRoleBinding references a ClusterRole, but not contain it. It can reference a ClusterRole in the global namespace,
// and adds who information via Subject.
type ClusterRoleBinding struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
v1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Subjects holds references to the objects the role applies to.
Subjects []Subject `json:"subjects" protobuf:"bytes,2,rep,name=subjects"`
// RoleRef can only reference a ClusterRole in the global namespace.
// If the RoleRef cannot be resolved, the Authorizer must return an error.
RoleRef RoleRef `json:"roleRef" protobuf:"bytes,3,opt,name=roleRef"`
}
// ClusterRoleBindingList is a collection of ClusterRoleBindings
type ClusterRoleBindingList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Items is a list of ClusterRoleBindings
Items []ClusterRoleBinding `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// ClusterRoleList is a collection of ClusterRoles
type ClusterRoleList struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Items is a list of ClusterRoles
Items []ClusterRole `json:"items" protobuf:"bytes,2,rep,name=items"`
}

View file

@ -0,0 +1,149 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
// This file contains a collection of methods that can be used from go-restful to
// generate Swagger API documentation for its models. Please read this PR for more
// information on the implementation: https://github.com/emicklei/go-restful/pull/215
//
// TODOs are ignored from the parser (e.g. TODO(andronat):... || TODO:...) if and only if
// they are on one line! For multiple line or blocks that you want to ignore use ---.
// Any context after a --- is ignored.
//
// Those methods can be generated by using hack/update-generated-swagger-docs.sh
// AUTO-GENERATED FUNCTIONS START HERE
var map_ClusterRole = map[string]string{
"": "ClusterRole is a cluster level, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding or ClusterRoleBinding.",
"metadata": "Standard object's metadata.",
"rules": "Rules holds all the PolicyRules for this ClusterRole",
}
func (ClusterRole) SwaggerDoc() map[string]string {
return map_ClusterRole
}
var map_ClusterRoleBinding = map[string]string{
"": "ClusterRoleBinding references a ClusterRole, but not contain it. It can reference a ClusterRole in the global namespace, and adds who information via Subject.",
"metadata": "Standard object's metadata.",
"subjects": "Subjects holds references to the objects the role applies to.",
"roleRef": "RoleRef can only reference a ClusterRole in the global namespace. If the RoleRef cannot be resolved, the Authorizer must return an error.",
}
func (ClusterRoleBinding) SwaggerDoc() map[string]string {
return map_ClusterRoleBinding
}
var map_ClusterRoleBindingList = map[string]string{
"": "ClusterRoleBindingList is a collection of ClusterRoleBindings",
"metadata": "Standard object's metadata.",
"items": "Items is a list of ClusterRoleBindings",
}
func (ClusterRoleBindingList) SwaggerDoc() map[string]string {
return map_ClusterRoleBindingList
}
var map_ClusterRoleList = map[string]string{
"": "ClusterRoleList is a collection of ClusterRoles",
"metadata": "Standard object's metadata.",
"items": "Items is a list of ClusterRoles",
}
func (ClusterRoleList) SwaggerDoc() map[string]string {
return map_ClusterRoleList
}
var map_PolicyRule = map[string]string{
"": "PolicyRule holds information that describes a policy rule, but does not contain information about who the rule applies to or which namespace the rule applies to.",
"verbs": "Verbs is a list of Verbs that apply to ALL the ResourceKinds and AttributeRestrictions contained in this rule. VerbAll represents all kinds.",
"attributeRestrictions": "AttributeRestrictions will vary depending on what the Authorizer/AuthorizationAttributeBuilder pair supports. If the Authorizer does not recognize how to handle the AttributeRestrictions, the Authorizer should report an error.",
"apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed.",
"resources": "Resources is a list of resources this rule applies to. ResourceAll represents all resources.",
"resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.",
"nonResourceURLs": "NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path This name is intentionally different than the internal type so that the DefaultConvert works nicely and because the ordering may be different. Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. Rules can either apply to API resources (such as \"pods\" or \"secrets\") or non-resource URL paths (such as \"/api\"), but not both.",
}
func (PolicyRule) SwaggerDoc() map[string]string {
return map_PolicyRule
}
var map_Role = map[string]string{
"": "Role is a namespaced, logical grouping of PolicyRules that can be referenced as a unit by a RoleBinding.",
"metadata": "Standard object's metadata.",
"rules": "Rules holds all the PolicyRules for this Role",
}
func (Role) SwaggerDoc() map[string]string {
return map_Role
}
var map_RoleBinding = map[string]string{
"": "RoleBinding references a role, but does not contain it. It can reference a Role in the same namespace or a ClusterRole in the global namespace. It adds who information via Subjects and namespace information by which namespace it exists in. RoleBindings in a given namespace only have effect in that namespace.",
"metadata": "Standard object's metadata.",
"subjects": "Subjects holds references to the objects the role applies to.",
"roleRef": "RoleRef can reference a Role in the current namespace or a ClusterRole in the global namespace. If the RoleRef cannot be resolved, the Authorizer must return an error.",
}
func (RoleBinding) SwaggerDoc() map[string]string {
return map_RoleBinding
}
var map_RoleBindingList = map[string]string{
"": "RoleBindingList is a collection of RoleBindings",
"metadata": "Standard object's metadata.",
"items": "Items is a list of RoleBindings",
}
func (RoleBindingList) SwaggerDoc() map[string]string {
return map_RoleBindingList
}
var map_RoleList = map[string]string{
"": "RoleList is a collection of Roles",
"metadata": "Standard object's metadata.",
"items": "Items is a list of Roles",
}
func (RoleList) SwaggerDoc() map[string]string {
return map_RoleList
}
var map_RoleRef = map[string]string{
"": "RoleRef contains information that points to the role being used",
"apiGroup": "APIGroup is the group for the resource being referenced",
"kind": "Kind is the type of resource being referenced",
"name": "Name is the name of resource being referenced",
}
func (RoleRef) SwaggerDoc() map[string]string {
return map_RoleRef
}
var map_Subject = map[string]string{
"": "Subject contains a reference to the object or user identities a role binding applies to. This can either hold a direct API object reference, or a value for non-objects such as user and group names.",
"kind": "Kind of object being referenced. Values defined by this API group are \"User\", \"Group\", and \"ServiceAccount\". If the Authorizer does not recognized the kind value, the Authorizer should report an error.",
"apiVersion": "APIVersion holds the API group and version of the referenced object.",
"name": "Name of the object being referenced.",
"namespace": "Namespace of the referenced object. If the object kind is non-namespace, such as \"User\" or \"Group\", and this value is not empty the Authorizer should report an error.",
}
func (Subject) SwaggerDoc() map[string]string {
return map_Subject
}
// AUTO-GENERATED FUNCTIONS END HERE

View file

@ -0,0 +1,463 @@
// +build !ignore_autogenerated
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This file was autogenerated by conversion-gen. Do not edit it manually!
package v1alpha1
import (
rbac "k8s.io/kubernetes/pkg/apis/rbac"
conversion "k8s.io/kubernetes/pkg/conversion"
runtime "k8s.io/kubernetes/pkg/runtime"
unsafe "unsafe"
)
func init() {
SchemeBuilder.Register(RegisterConversions)
}
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(scheme *runtime.Scheme) error {
return scheme.AddGeneratedConversionFuncs(
Convert_v1alpha1_ClusterRole_To_rbac_ClusterRole,
Convert_rbac_ClusterRole_To_v1alpha1_ClusterRole,
Convert_v1alpha1_ClusterRoleBinding_To_rbac_ClusterRoleBinding,
Convert_rbac_ClusterRoleBinding_To_v1alpha1_ClusterRoleBinding,
Convert_v1alpha1_ClusterRoleBindingBuilder_To_rbac_ClusterRoleBindingBuilder,
Convert_rbac_ClusterRoleBindingBuilder_To_v1alpha1_ClusterRoleBindingBuilder,
Convert_v1alpha1_ClusterRoleBindingList_To_rbac_ClusterRoleBindingList,
Convert_rbac_ClusterRoleBindingList_To_v1alpha1_ClusterRoleBindingList,
Convert_v1alpha1_ClusterRoleList_To_rbac_ClusterRoleList,
Convert_rbac_ClusterRoleList_To_v1alpha1_ClusterRoleList,
Convert_v1alpha1_PolicyRule_To_rbac_PolicyRule,
Convert_rbac_PolicyRule_To_v1alpha1_PolicyRule,
Convert_v1alpha1_PolicyRuleBuilder_To_rbac_PolicyRuleBuilder,
Convert_rbac_PolicyRuleBuilder_To_v1alpha1_PolicyRuleBuilder,
Convert_v1alpha1_Role_To_rbac_Role,
Convert_rbac_Role_To_v1alpha1_Role,
Convert_v1alpha1_RoleBinding_To_rbac_RoleBinding,
Convert_rbac_RoleBinding_To_v1alpha1_RoleBinding,
Convert_v1alpha1_RoleBindingList_To_rbac_RoleBindingList,
Convert_rbac_RoleBindingList_To_v1alpha1_RoleBindingList,
Convert_v1alpha1_RoleList_To_rbac_RoleList,
Convert_rbac_RoleList_To_v1alpha1_RoleList,
Convert_v1alpha1_RoleRef_To_rbac_RoleRef,
Convert_rbac_RoleRef_To_v1alpha1_RoleRef,
Convert_v1alpha1_Subject_To_rbac_Subject,
Convert_rbac_Subject_To_v1alpha1_Subject,
)
}
func autoConvert_v1alpha1_ClusterRole_To_rbac_ClusterRole(in *ClusterRole, out *rbac.ClusterRole, s conversion.Scope) error {
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]rbac.PolicyRule, len(*in))
for i := range *in {
if err := Convert_v1alpha1_PolicyRule_To_rbac_PolicyRule(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Rules = nil
}
return nil
}
func Convert_v1alpha1_ClusterRole_To_rbac_ClusterRole(in *ClusterRole, out *rbac.ClusterRole, s conversion.Scope) error {
return autoConvert_v1alpha1_ClusterRole_To_rbac_ClusterRole(in, out, s)
}
func autoConvert_rbac_ClusterRole_To_v1alpha1_ClusterRole(in *rbac.ClusterRole, out *ClusterRole, s conversion.Scope) error {
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]PolicyRule, len(*in))
for i := range *in {
if err := Convert_rbac_PolicyRule_To_v1alpha1_PolicyRule(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Rules = nil
}
return nil
}
func Convert_rbac_ClusterRole_To_v1alpha1_ClusterRole(in *rbac.ClusterRole, out *ClusterRole, s conversion.Scope) error {
return autoConvert_rbac_ClusterRole_To_v1alpha1_ClusterRole(in, out, s)
}
func autoConvert_v1alpha1_ClusterRoleBinding_To_rbac_ClusterRoleBinding(in *ClusterRoleBinding, out *rbac.ClusterRoleBinding, s conversion.Scope) error {
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
out.Subjects = *(*[]rbac.Subject)(unsafe.Pointer(&in.Subjects))
if err := Convert_v1alpha1_RoleRef_To_rbac_RoleRef(&in.RoleRef, &out.RoleRef, s); err != nil {
return err
}
return nil
}
func Convert_v1alpha1_ClusterRoleBinding_To_rbac_ClusterRoleBinding(in *ClusterRoleBinding, out *rbac.ClusterRoleBinding, s conversion.Scope) error {
return autoConvert_v1alpha1_ClusterRoleBinding_To_rbac_ClusterRoleBinding(in, out, s)
}
func autoConvert_rbac_ClusterRoleBinding_To_v1alpha1_ClusterRoleBinding(in *rbac.ClusterRoleBinding, out *ClusterRoleBinding, s conversion.Scope) error {
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
out.Subjects = *(*[]Subject)(unsafe.Pointer(&in.Subjects))
if err := Convert_rbac_RoleRef_To_v1alpha1_RoleRef(&in.RoleRef, &out.RoleRef, s); err != nil {
return err
}
return nil
}
func Convert_rbac_ClusterRoleBinding_To_v1alpha1_ClusterRoleBinding(in *rbac.ClusterRoleBinding, out *ClusterRoleBinding, s conversion.Scope) error {
return autoConvert_rbac_ClusterRoleBinding_To_v1alpha1_ClusterRoleBinding(in, out, s)
}
func autoConvert_v1alpha1_ClusterRoleBindingBuilder_To_rbac_ClusterRoleBindingBuilder(in *ClusterRoleBindingBuilder, out *rbac.ClusterRoleBindingBuilder, s conversion.Scope) error {
if err := Convert_v1alpha1_ClusterRoleBinding_To_rbac_ClusterRoleBinding(&in.ClusterRoleBinding, &out.ClusterRoleBinding, s); err != nil {
return err
}
return nil
}
func Convert_v1alpha1_ClusterRoleBindingBuilder_To_rbac_ClusterRoleBindingBuilder(in *ClusterRoleBindingBuilder, out *rbac.ClusterRoleBindingBuilder, s conversion.Scope) error {
return autoConvert_v1alpha1_ClusterRoleBindingBuilder_To_rbac_ClusterRoleBindingBuilder(in, out, s)
}
func autoConvert_rbac_ClusterRoleBindingBuilder_To_v1alpha1_ClusterRoleBindingBuilder(in *rbac.ClusterRoleBindingBuilder, out *ClusterRoleBindingBuilder, s conversion.Scope) error {
if err := Convert_rbac_ClusterRoleBinding_To_v1alpha1_ClusterRoleBinding(&in.ClusterRoleBinding, &out.ClusterRoleBinding, s); err != nil {
return err
}
return nil
}
func Convert_rbac_ClusterRoleBindingBuilder_To_v1alpha1_ClusterRoleBindingBuilder(in *rbac.ClusterRoleBindingBuilder, out *ClusterRoleBindingBuilder, s conversion.Scope) error {
return autoConvert_rbac_ClusterRoleBindingBuilder_To_v1alpha1_ClusterRoleBindingBuilder(in, out, s)
}
func autoConvert_v1alpha1_ClusterRoleBindingList_To_rbac_ClusterRoleBindingList(in *ClusterRoleBindingList, out *rbac.ClusterRoleBindingList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]rbac.ClusterRoleBinding)(unsafe.Pointer(&in.Items))
return nil
}
func Convert_v1alpha1_ClusterRoleBindingList_To_rbac_ClusterRoleBindingList(in *ClusterRoleBindingList, out *rbac.ClusterRoleBindingList, s conversion.Scope) error {
return autoConvert_v1alpha1_ClusterRoleBindingList_To_rbac_ClusterRoleBindingList(in, out, s)
}
func autoConvert_rbac_ClusterRoleBindingList_To_v1alpha1_ClusterRoleBindingList(in *rbac.ClusterRoleBindingList, out *ClusterRoleBindingList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]ClusterRoleBinding)(unsafe.Pointer(&in.Items))
return nil
}
func Convert_rbac_ClusterRoleBindingList_To_v1alpha1_ClusterRoleBindingList(in *rbac.ClusterRoleBindingList, out *ClusterRoleBindingList, s conversion.Scope) error {
return autoConvert_rbac_ClusterRoleBindingList_To_v1alpha1_ClusterRoleBindingList(in, out, s)
}
func autoConvert_v1alpha1_ClusterRoleList_To_rbac_ClusterRoleList(in *ClusterRoleList, out *rbac.ClusterRoleList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]rbac.ClusterRole, len(*in))
for i := range *in {
if err := Convert_v1alpha1_ClusterRole_To_rbac_ClusterRole(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
func Convert_v1alpha1_ClusterRoleList_To_rbac_ClusterRoleList(in *ClusterRoleList, out *rbac.ClusterRoleList, s conversion.Scope) error {
return autoConvert_v1alpha1_ClusterRoleList_To_rbac_ClusterRoleList(in, out, s)
}
func autoConvert_rbac_ClusterRoleList_To_v1alpha1_ClusterRoleList(in *rbac.ClusterRoleList, out *ClusterRoleList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ClusterRole, len(*in))
for i := range *in {
if err := Convert_rbac_ClusterRole_To_v1alpha1_ClusterRole(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
func Convert_rbac_ClusterRoleList_To_v1alpha1_ClusterRoleList(in *rbac.ClusterRoleList, out *ClusterRoleList, s conversion.Scope) error {
return autoConvert_rbac_ClusterRoleList_To_v1alpha1_ClusterRoleList(in, out, s)
}
func autoConvert_v1alpha1_PolicyRule_To_rbac_PolicyRule(in *PolicyRule, out *rbac.PolicyRule, s conversion.Scope) error {
out.Verbs = *(*[]string)(unsafe.Pointer(&in.Verbs))
if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.AttributeRestrictions, &out.AttributeRestrictions, s); err != nil {
return err
}
out.APIGroups = *(*[]string)(unsafe.Pointer(&in.APIGroups))
out.Resources = *(*[]string)(unsafe.Pointer(&in.Resources))
out.ResourceNames = *(*[]string)(unsafe.Pointer(&in.ResourceNames))
out.NonResourceURLs = *(*[]string)(unsafe.Pointer(&in.NonResourceURLs))
return nil
}
func Convert_v1alpha1_PolicyRule_To_rbac_PolicyRule(in *PolicyRule, out *rbac.PolicyRule, s conversion.Scope) error {
return autoConvert_v1alpha1_PolicyRule_To_rbac_PolicyRule(in, out, s)
}
func autoConvert_rbac_PolicyRule_To_v1alpha1_PolicyRule(in *rbac.PolicyRule, out *PolicyRule, s conversion.Scope) error {
out.Verbs = *(*[]string)(unsafe.Pointer(&in.Verbs))
if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.AttributeRestrictions, &out.AttributeRestrictions, s); err != nil {
return err
}
out.APIGroups = *(*[]string)(unsafe.Pointer(&in.APIGroups))
out.Resources = *(*[]string)(unsafe.Pointer(&in.Resources))
out.ResourceNames = *(*[]string)(unsafe.Pointer(&in.ResourceNames))
out.NonResourceURLs = *(*[]string)(unsafe.Pointer(&in.NonResourceURLs))
return nil
}
func Convert_rbac_PolicyRule_To_v1alpha1_PolicyRule(in *rbac.PolicyRule, out *PolicyRule, s conversion.Scope) error {
return autoConvert_rbac_PolicyRule_To_v1alpha1_PolicyRule(in, out, s)
}
func autoConvert_v1alpha1_PolicyRuleBuilder_To_rbac_PolicyRuleBuilder(in *PolicyRuleBuilder, out *rbac.PolicyRuleBuilder, s conversion.Scope) error {
if err := Convert_v1alpha1_PolicyRule_To_rbac_PolicyRule(&in.PolicyRule, &out.PolicyRule, s); err != nil {
return err
}
return nil
}
func Convert_v1alpha1_PolicyRuleBuilder_To_rbac_PolicyRuleBuilder(in *PolicyRuleBuilder, out *rbac.PolicyRuleBuilder, s conversion.Scope) error {
return autoConvert_v1alpha1_PolicyRuleBuilder_To_rbac_PolicyRuleBuilder(in, out, s)
}
func autoConvert_rbac_PolicyRuleBuilder_To_v1alpha1_PolicyRuleBuilder(in *rbac.PolicyRuleBuilder, out *PolicyRuleBuilder, s conversion.Scope) error {
if err := Convert_rbac_PolicyRule_To_v1alpha1_PolicyRule(&in.PolicyRule, &out.PolicyRule, s); err != nil {
return err
}
return nil
}
func Convert_rbac_PolicyRuleBuilder_To_v1alpha1_PolicyRuleBuilder(in *rbac.PolicyRuleBuilder, out *PolicyRuleBuilder, s conversion.Scope) error {
return autoConvert_rbac_PolicyRuleBuilder_To_v1alpha1_PolicyRuleBuilder(in, out, s)
}
func autoConvert_v1alpha1_Role_To_rbac_Role(in *Role, out *rbac.Role, s conversion.Scope) error {
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]rbac.PolicyRule, len(*in))
for i := range *in {
if err := Convert_v1alpha1_PolicyRule_To_rbac_PolicyRule(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Rules = nil
}
return nil
}
func Convert_v1alpha1_Role_To_rbac_Role(in *Role, out *rbac.Role, s conversion.Scope) error {
return autoConvert_v1alpha1_Role_To_rbac_Role(in, out, s)
}
func autoConvert_rbac_Role_To_v1alpha1_Role(in *rbac.Role, out *Role, s conversion.Scope) error {
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]PolicyRule, len(*in))
for i := range *in {
if err := Convert_rbac_PolicyRule_To_v1alpha1_PolicyRule(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Rules = nil
}
return nil
}
func Convert_rbac_Role_To_v1alpha1_Role(in *rbac.Role, out *Role, s conversion.Scope) error {
return autoConvert_rbac_Role_To_v1alpha1_Role(in, out, s)
}
func autoConvert_v1alpha1_RoleBinding_To_rbac_RoleBinding(in *RoleBinding, out *rbac.RoleBinding, s conversion.Scope) error {
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
out.Subjects = *(*[]rbac.Subject)(unsafe.Pointer(&in.Subjects))
if err := Convert_v1alpha1_RoleRef_To_rbac_RoleRef(&in.RoleRef, &out.RoleRef, s); err != nil {
return err
}
return nil
}
func Convert_v1alpha1_RoleBinding_To_rbac_RoleBinding(in *RoleBinding, out *rbac.RoleBinding, s conversion.Scope) error {
return autoConvert_v1alpha1_RoleBinding_To_rbac_RoleBinding(in, out, s)
}
func autoConvert_rbac_RoleBinding_To_v1alpha1_RoleBinding(in *rbac.RoleBinding, out *RoleBinding, s conversion.Scope) error {
// TODO: Inefficient conversion - can we improve it?
if err := s.Convert(&in.ObjectMeta, &out.ObjectMeta, 0); err != nil {
return err
}
out.Subjects = *(*[]Subject)(unsafe.Pointer(&in.Subjects))
if err := Convert_rbac_RoleRef_To_v1alpha1_RoleRef(&in.RoleRef, &out.RoleRef, s); err != nil {
return err
}
return nil
}
func Convert_rbac_RoleBinding_To_v1alpha1_RoleBinding(in *rbac.RoleBinding, out *RoleBinding, s conversion.Scope) error {
return autoConvert_rbac_RoleBinding_To_v1alpha1_RoleBinding(in, out, s)
}
func autoConvert_v1alpha1_RoleBindingList_To_rbac_RoleBindingList(in *RoleBindingList, out *rbac.RoleBindingList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]rbac.RoleBinding)(unsafe.Pointer(&in.Items))
return nil
}
func Convert_v1alpha1_RoleBindingList_To_rbac_RoleBindingList(in *RoleBindingList, out *rbac.RoleBindingList, s conversion.Scope) error {
return autoConvert_v1alpha1_RoleBindingList_To_rbac_RoleBindingList(in, out, s)
}
func autoConvert_rbac_RoleBindingList_To_v1alpha1_RoleBindingList(in *rbac.RoleBindingList, out *RoleBindingList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
out.Items = *(*[]RoleBinding)(unsafe.Pointer(&in.Items))
return nil
}
func Convert_rbac_RoleBindingList_To_v1alpha1_RoleBindingList(in *rbac.RoleBindingList, out *RoleBindingList, s conversion.Scope) error {
return autoConvert_rbac_RoleBindingList_To_v1alpha1_RoleBindingList(in, out, s)
}
func autoConvert_v1alpha1_RoleList_To_rbac_RoleList(in *RoleList, out *rbac.RoleList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]rbac.Role, len(*in))
for i := range *in {
if err := Convert_v1alpha1_Role_To_rbac_Role(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
func Convert_v1alpha1_RoleList_To_rbac_RoleList(in *RoleList, out *rbac.RoleList, s conversion.Scope) error {
return autoConvert_v1alpha1_RoleList_To_rbac_RoleList(in, out, s)
}
func autoConvert_rbac_RoleList_To_v1alpha1_RoleList(in *rbac.RoleList, out *RoleList, s conversion.Scope) error {
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Role, len(*in))
for i := range *in {
if err := Convert_rbac_Role_To_v1alpha1_Role(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
func Convert_rbac_RoleList_To_v1alpha1_RoleList(in *rbac.RoleList, out *RoleList, s conversion.Scope) error {
return autoConvert_rbac_RoleList_To_v1alpha1_RoleList(in, out, s)
}
func autoConvert_v1alpha1_RoleRef_To_rbac_RoleRef(in *RoleRef, out *rbac.RoleRef, s conversion.Scope) error {
out.APIGroup = in.APIGroup
out.Kind = in.Kind
out.Name = in.Name
return nil
}
func Convert_v1alpha1_RoleRef_To_rbac_RoleRef(in *RoleRef, out *rbac.RoleRef, s conversion.Scope) error {
return autoConvert_v1alpha1_RoleRef_To_rbac_RoleRef(in, out, s)
}
func autoConvert_rbac_RoleRef_To_v1alpha1_RoleRef(in *rbac.RoleRef, out *RoleRef, s conversion.Scope) error {
out.APIGroup = in.APIGroup
out.Kind = in.Kind
out.Name = in.Name
return nil
}
func Convert_rbac_RoleRef_To_v1alpha1_RoleRef(in *rbac.RoleRef, out *RoleRef, s conversion.Scope) error {
return autoConvert_rbac_RoleRef_To_v1alpha1_RoleRef(in, out, s)
}
func autoConvert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject, s conversion.Scope) error {
out.Kind = in.Kind
out.APIVersion = in.APIVersion
out.Name = in.Name
out.Namespace = in.Namespace
return nil
}
func Convert_v1alpha1_Subject_To_rbac_Subject(in *Subject, out *rbac.Subject, s conversion.Scope) error {
return autoConvert_v1alpha1_Subject_To_rbac_Subject(in, out, s)
}
func autoConvert_rbac_Subject_To_v1alpha1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error {
out.Kind = in.Kind
out.APIVersion = in.APIVersion
out.Name = in.Name
out.Namespace = in.Namespace
return nil
}
func Convert_rbac_Subject_To_v1alpha1_Subject(in *rbac.Subject, out *Subject, s conversion.Scope) error {
return autoConvert_rbac_Subject_To_v1alpha1_Subject(in, out, s)
}

View file

@ -0,0 +1,293 @@
// +build !ignore_autogenerated
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
package v1alpha1
import (
v1 "k8s.io/kubernetes/pkg/api/v1"
conversion "k8s.io/kubernetes/pkg/conversion"
runtime "k8s.io/kubernetes/pkg/runtime"
reflect "reflect"
)
func init() {
SchemeBuilder.Register(RegisterDeepCopies)
}
// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
// to allow building arbitrary schemes.
func RegisterDeepCopies(scheme *runtime.Scheme) error {
return scheme.AddGeneratedDeepCopyFuncs(
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_ClusterRole, InType: reflect.TypeOf(&ClusterRole{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_ClusterRoleBinding, InType: reflect.TypeOf(&ClusterRoleBinding{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_ClusterRoleBindingList, InType: reflect.TypeOf(&ClusterRoleBindingList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_ClusterRoleList, InType: reflect.TypeOf(&ClusterRoleList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_PolicyRule, InType: reflect.TypeOf(&PolicyRule{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_Role, InType: reflect.TypeOf(&Role{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_RoleBinding, InType: reflect.TypeOf(&RoleBinding{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_RoleBindingList, InType: reflect.TypeOf(&RoleBindingList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_RoleList, InType: reflect.TypeOf(&RoleList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_RoleRef, InType: reflect.TypeOf(&RoleRef{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_v1alpha1_Subject, InType: reflect.TypeOf(&Subject{})},
)
}
func DeepCopy_v1alpha1_ClusterRole(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*ClusterRole)
out := out.(*ClusterRole)
out.TypeMeta = in.TypeMeta
if err := v1.DeepCopy_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]PolicyRule, len(*in))
for i := range *in {
if err := DeepCopy_v1alpha1_PolicyRule(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Rules = nil
}
return nil
}
}
func DeepCopy_v1alpha1_ClusterRoleBinding(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*ClusterRoleBinding)
out := out.(*ClusterRoleBinding)
out.TypeMeta = in.TypeMeta
if err := v1.DeepCopy_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if in.Subjects != nil {
in, out := &in.Subjects, &out.Subjects
*out = make([]Subject, len(*in))
for i := range *in {
(*out)[i] = (*in)[i]
}
} else {
out.Subjects = nil
}
out.RoleRef = in.RoleRef
return nil
}
}
func DeepCopy_v1alpha1_ClusterRoleBindingList(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*ClusterRoleBindingList)
out := out.(*ClusterRoleBindingList)
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ClusterRoleBinding, len(*in))
for i := range *in {
if err := DeepCopy_v1alpha1_ClusterRoleBinding(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
}
func DeepCopy_v1alpha1_ClusterRoleList(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*ClusterRoleList)
out := out.(*ClusterRoleList)
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ClusterRole, len(*in))
for i := range *in {
if err := DeepCopy_v1alpha1_ClusterRole(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
}
func DeepCopy_v1alpha1_PolicyRule(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*PolicyRule)
out := out.(*PolicyRule)
if in.Verbs != nil {
in, out := &in.Verbs, &out.Verbs
*out = make([]string, len(*in))
copy(*out, *in)
} else {
out.Verbs = nil
}
if err := runtime.DeepCopy_runtime_RawExtension(&in.AttributeRestrictions, &out.AttributeRestrictions, c); err != nil {
return err
}
if in.APIGroups != nil {
in, out := &in.APIGroups, &out.APIGroups
*out = make([]string, len(*in))
copy(*out, *in)
} else {
out.APIGroups = nil
}
if in.Resources != nil {
in, out := &in.Resources, &out.Resources
*out = make([]string, len(*in))
copy(*out, *in)
} else {
out.Resources = nil
}
if in.ResourceNames != nil {
in, out := &in.ResourceNames, &out.ResourceNames
*out = make([]string, len(*in))
copy(*out, *in)
} else {
out.ResourceNames = nil
}
if in.NonResourceURLs != nil {
in, out := &in.NonResourceURLs, &out.NonResourceURLs
*out = make([]string, len(*in))
copy(*out, *in)
} else {
out.NonResourceURLs = nil
}
return nil
}
}
func DeepCopy_v1alpha1_Role(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*Role)
out := out.(*Role)
out.TypeMeta = in.TypeMeta
if err := v1.DeepCopy_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]PolicyRule, len(*in))
for i := range *in {
if err := DeepCopy_v1alpha1_PolicyRule(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Rules = nil
}
return nil
}
}
func DeepCopy_v1alpha1_RoleBinding(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*RoleBinding)
out := out.(*RoleBinding)
out.TypeMeta = in.TypeMeta
if err := v1.DeepCopy_v1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if in.Subjects != nil {
in, out := &in.Subjects, &out.Subjects
*out = make([]Subject, len(*in))
for i := range *in {
(*out)[i] = (*in)[i]
}
} else {
out.Subjects = nil
}
out.RoleRef = in.RoleRef
return nil
}
}
func DeepCopy_v1alpha1_RoleBindingList(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*RoleBindingList)
out := out.(*RoleBindingList)
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]RoleBinding, len(*in))
for i := range *in {
if err := DeepCopy_v1alpha1_RoleBinding(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
}
func DeepCopy_v1alpha1_RoleList(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*RoleList)
out := out.(*RoleList)
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Role, len(*in))
for i := range *in {
if err := DeepCopy_v1alpha1_Role(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
}
func DeepCopy_v1alpha1_RoleRef(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*RoleRef)
out := out.(*RoleRef)
out.APIGroup = in.APIGroup
out.Kind = in.Kind
out.Name = in.Name
return nil
}
}
func DeepCopy_v1alpha1_Subject(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*Subject)
out := out.(*Subject)
out.Kind = in.Kind
out.APIVersion = in.APIVersion
out.Name = in.Name
out.Namespace = in.Namespace
return nil
}
}

View file

@ -0,0 +1,58 @@
// +build !ignore_autogenerated
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This file was autogenerated by defaulter-gen. Do not edit it manually!
package v1alpha1
import (
runtime "k8s.io/kubernetes/pkg/runtime"
)
// RegisterDefaults adds defaulters functions to the given scheme.
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {
scheme.AddTypeDefaultingFunc(&ClusterRoleBinding{}, func(obj interface{}) { SetObjectDefaults_ClusterRoleBinding(obj.(*ClusterRoleBinding)) })
scheme.AddTypeDefaultingFunc(&ClusterRoleBindingList{}, func(obj interface{}) { SetObjectDefaults_ClusterRoleBindingList(obj.(*ClusterRoleBindingList)) })
scheme.AddTypeDefaultingFunc(&RoleBinding{}, func(obj interface{}) { SetObjectDefaults_RoleBinding(obj.(*RoleBinding)) })
scheme.AddTypeDefaultingFunc(&RoleBindingList{}, func(obj interface{}) { SetObjectDefaults_RoleBindingList(obj.(*RoleBindingList)) })
return nil
}
func SetObjectDefaults_ClusterRoleBinding(in *ClusterRoleBinding) {
SetDefaults_ClusterRoleBinding(in)
}
func SetObjectDefaults_ClusterRoleBindingList(in *ClusterRoleBindingList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_ClusterRoleBinding(a)
}
}
func SetObjectDefaults_RoleBinding(in *RoleBinding) {
SetDefaults_RoleBinding(in)
}
func SetObjectDefaults_RoleBindingList(in *RoleBindingList) {
for i := range in.Items {
a := &in.Items[i]
SetObjectDefaults_RoleBinding(a)
}
}

View file

@ -0,0 +1,51 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = [
"policy_comparator.go",
"rulevalidation.go",
"validation.go",
],
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/errors:go_default_library",
"//pkg/api/validation:go_default_library",
"//pkg/api/validation/path:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/serviceaccount:go_default_library",
"//pkg/util/errors:go_default_library",
"//pkg/util/validation/field:go_default_library",
"//vendor:github.com/golang/glog",
],
)
go_test(
name = "go_default_test",
srcs = [
"policy_comparator_test.go",
"rulevalidation_test.go",
"validation_test.go",
],
library = "go_default_library",
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/util/diff:go_default_library",
"//pkg/util/validation/field:go_default_library",
],
)

View file

@ -0,0 +1,148 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"strings"
"k8s.io/kubernetes/pkg/apis/rbac"
)
// Covers determines whether or not the ownerRules cover the servantRules in terms of allowed actions.
// It returns whether or not the ownerRules cover and a list of the rules that the ownerRules do not cover.
func Covers(ownerRules, servantRules []rbac.PolicyRule) (bool, []rbac.PolicyRule) {
// 1. Break every servantRule into individual rule tuples: group, verb, resource, resourceName
// 2. Compare the mini-rules against each owner rule. Because the breakdown is down to the most atomic level, we're guaranteed that each mini-servant rule will be either fully covered or not covered by a single owner rule
// 3. Any left over mini-rules means that we are not covered and we have a nice list of them.
// TODO: it might be nice to collapse the list down into something more human readable
subrules := []rbac.PolicyRule{}
for _, servantRule := range servantRules {
subrules = append(subrules, breakdownRule(servantRule)...)
}
uncoveredRules := []rbac.PolicyRule{}
for _, subrule := range subrules {
covered := false
for _, ownerRule := range ownerRules {
if ruleCovers(ownerRule, subrule) {
covered = true
break
}
}
if !covered {
uncoveredRules = append(uncoveredRules, subrule)
}
}
return (len(uncoveredRules) == 0), uncoveredRules
}
// breadownRule takes a rule and builds an equivalent list of rules that each have at most one verb, one
// resource, and one resource name
func breakdownRule(rule rbac.PolicyRule) []rbac.PolicyRule {
subrules := []rbac.PolicyRule{}
for _, group := range rule.APIGroups {
for _, resource := range rule.Resources {
for _, verb := range rule.Verbs {
if len(rule.ResourceNames) > 0 {
for _, resourceName := range rule.ResourceNames {
subrules = append(subrules, rbac.PolicyRule{APIGroups: []string{group}, Resources: []string{resource}, Verbs: []string{verb}, ResourceNames: []string{resourceName}})
}
} else {
subrules = append(subrules, rbac.PolicyRule{APIGroups: []string{group}, Resources: []string{resource}, Verbs: []string{verb}})
}
}
}
}
// Non-resource URLs are unique because they only combine with verbs.
for _, nonResourceURL := range rule.NonResourceURLs {
for _, verb := range rule.Verbs {
subrules = append(subrules, rbac.PolicyRule{NonResourceURLs: []string{nonResourceURL}, Verbs: []string{verb}})
}
}
return subrules
}
func has(set []string, ele string) bool {
for _, s := range set {
if s == ele {
return true
}
}
return false
}
func hasAll(set, contains []string) bool {
owning := make(map[string]struct{}, len(set))
for _, ele := range set {
owning[ele] = struct{}{}
}
for _, ele := range contains {
if _, ok := owning[ele]; !ok {
return false
}
}
return true
}
func nonResourceURLsCoversAll(set, covers []string) bool {
for _, path := range covers {
covered := false
for _, owner := range set {
if nonResourceURLCovers(owner, path) {
covered = true
break
}
}
if !covered {
return false
}
}
return true
}
func nonResourceURLCovers(ownerPath, subPath string) bool {
if ownerPath == subPath {
return true
}
return strings.HasSuffix(ownerPath, "*") && strings.HasPrefix(subPath, strings.TrimRight(ownerPath, "*"))
}
// ruleCovers determines whether the ownerRule (which may have multiple verbs, resources, and resourceNames) covers
// the subrule (which may only contain at most one verb, resource, and resourceName)
func ruleCovers(ownerRule, subRule rbac.PolicyRule) bool {
verbMatches := has(ownerRule.Verbs, rbac.VerbAll) || hasAll(ownerRule.Verbs, subRule.Verbs)
groupMatches := has(ownerRule.APIGroups, rbac.APIGroupAll) || hasAll(ownerRule.APIGroups, subRule.APIGroups)
resourceMatches := has(ownerRule.Resources, rbac.ResourceAll) || hasAll(ownerRule.Resources, subRule.Resources)
nonResourceURLMatches := nonResourceURLsCoversAll(ownerRule.NonResourceURLs, subRule.NonResourceURLs)
resourceNameMatches := false
if len(subRule.ResourceNames) == 0 {
resourceNameMatches = (len(ownerRule.ResourceNames) == 0)
} else {
resourceNameMatches = (len(ownerRule.ResourceNames) == 0) || hasAll(ownerRule.ResourceNames, subRule.ResourceNames)
}
return verbMatches && groupMatches && resourceMatches && resourceNameMatches && nonResourceURLMatches
}

View file

@ -0,0 +1,402 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"reflect"
"testing"
"k8s.io/kubernetes/pkg/apis/rbac"
)
type escalationTest struct {
ownerRules []rbac.PolicyRule
servantRules []rbac.PolicyRule
expectedCovered bool
expectedUncoveredRules []rbac.PolicyRule
}
func TestCoversExactMatch(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"builds"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"builds"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversMultipleRulesCoveringSingleRule(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"delete"}, Resources: []string{"deployments"}},
{APIGroups: []string{"v1"}, Verbs: []string{"delete"}, Resources: []string{"builds"}},
{APIGroups: []string{"v1"}, Verbs: []string{"update"}, Resources: []string{"builds", "deployments"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"delete", "update"}, Resources: []string{"builds", "deployments"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversMultipleAPIGroupsCoveringSingleRule(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"group1"}, Verbs: []string{"delete"}, Resources: []string{"deployments"}},
{APIGroups: []string{"group1"}, Verbs: []string{"delete"}, Resources: []string{"builds"}},
{APIGroups: []string{"group1"}, Verbs: []string{"update"}, Resources: []string{"builds", "deployments"}},
{APIGroups: []string{"group2"}, Verbs: []string{"delete"}, Resources: []string{"deployments"}},
{APIGroups: []string{"group2"}, Verbs: []string{"delete"}, Resources: []string{"builds"}},
{APIGroups: []string{"group2"}, Verbs: []string{"update"}, Resources: []string{"builds", "deployments"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"group1", "group2"}, Verbs: []string{"delete", "update"}, Resources: []string{"builds", "deployments"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversSingleAPIGroupsCoveringMultiple(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"group1", "group2"}, Verbs: []string{"delete", "update"}, Resources: []string{"builds", "deployments"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"group1"}, Verbs: []string{"delete"}, Resources: []string{"deployments"}},
{APIGroups: []string{"group1"}, Verbs: []string{"delete"}, Resources: []string{"builds"}},
{APIGroups: []string{"group1"}, Verbs: []string{"update"}, Resources: []string{"builds", "deployments"}},
{APIGroups: []string{"group2"}, Verbs: []string{"delete"}, Resources: []string{"deployments"}},
{APIGroups: []string{"group2"}, Verbs: []string{"delete"}, Resources: []string{"builds"}},
{APIGroups: []string{"group2"}, Verbs: []string{"update"}, Resources: []string{"builds", "deployments"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversMultipleRulesMissingSingleVerbResourceCombination(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"delete", "update"}, Resources: []string{"builds", "deployments"}},
{APIGroups: []string{"v1"}, Verbs: []string{"delete"}, Resources: []string{"pods"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"delete", "update"}, Resources: []string{"builds", "deployments", "pods"}},
},
expectedCovered: false,
expectedUncoveredRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"update"}, Resources: []string{"pods"}},
},
}.test(t)
}
func TestCoversAPIGroupStarCoveringMultiple(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"*"}, Verbs: []string{"get"}, Resources: []string{"roles"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"group1", "group2"}, Verbs: []string{"get"}, Resources: []string{"roles"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversEnumerationNotCoveringAPIGroupStar(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"dummy-group"}, Verbs: []string{"get"}, Resources: []string{"roles"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"*"}, Verbs: []string{"get"}, Resources: []string{"roles"}},
},
expectedCovered: false,
expectedUncoveredRules: []rbac.PolicyRule{
{APIGroups: []string{"*"}, Verbs: []string{"get"}, Resources: []string{"roles"}},
},
}.test(t)
}
func TestCoversAPIGroupStarCoveringStar(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"*"}, Verbs: []string{"get"}, Resources: []string{"roles"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"*"}, Verbs: []string{"get"}, Resources: []string{"roles"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversVerbStarCoveringMultiple(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"*"}, Resources: []string{"roles"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"watch", "list"}, Resources: []string{"roles"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversEnumerationNotCoveringVerbStar(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get", "list", "watch", "create", "update", "delete", "exec"}, Resources: []string{"roles"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"*"}, Resources: []string{"roles"}},
},
expectedCovered: false,
expectedUncoveredRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"*"}, Resources: []string{"roles"}},
},
}.test(t)
}
func TestCoversVerbStarCoveringStar(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"*"}, Resources: []string{"roles"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"*"}, Resources: []string{"roles"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversResourceStarCoveringMultiple(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"*"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"resourcegroup:deployments"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversEnumerationNotCoveringResourceStar(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"roles", "resourcegroup:deployments"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"*"}},
},
expectedCovered: false,
expectedUncoveredRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"*"}},
},
}.test(t)
}
func TestCoversResourceStarCoveringStar(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"*"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"*"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversResourceNameEmptyCoveringMultiple(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"pods"}, ResourceNames: []string{}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"pods"}, ResourceNames: []string{"foo", "bar"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversEnumerationNotCoveringResourceNameEmpty(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"pods"}, ResourceNames: []string{"foo", "bar"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"pods"}, ResourceNames: []string{}},
},
expectedCovered: false,
expectedUncoveredRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"pods"}},
},
}.test(t)
}
func TestCoversNonResourceURLs(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{NonResourceURLs: []string{"/apis"}, Verbs: []string{"*"}},
},
servantRules: []rbac.PolicyRule{
{NonResourceURLs: []string{"/apis"}, Verbs: []string{"*"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversNonResourceURLsStar(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{NonResourceURLs: []string{"*"}, Verbs: []string{"*"}},
},
servantRules: []rbac.PolicyRule{
{NonResourceURLs: []string{"/apis", "/apis/v1", "/"}, Verbs: []string{"*"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversNonResourceURLsStarAfterPrefixDoesntCover(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{NonResourceURLs: []string{"/apis/*"}, Verbs: []string{"*"}},
},
servantRules: []rbac.PolicyRule{
{NonResourceURLs: []string{"/apis", "/apis/v1"}, Verbs: []string{"get"}},
},
expectedCovered: false,
expectedUncoveredRules: []rbac.PolicyRule{
{NonResourceURLs: []string{"/apis"}, Verbs: []string{"get"}},
},
}.test(t)
}
func TestCoversNonResourceURLsStarAfterPrefix(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{NonResourceURLs: []string{"/apis/*"}, Verbs: []string{"*"}},
},
servantRules: []rbac.PolicyRule{
{NonResourceURLs: []string{"/apis/v1/foo", "/apis/v1"}, Verbs: []string{"get"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversNonResourceURLsWithOtherFields(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"builds"}, NonResourceURLs: []string{"/apis"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"builds"}, NonResourceURLs: []string{"/apis"}},
},
expectedCovered: true,
expectedUncoveredRules: []rbac.PolicyRule{},
}.test(t)
}
func TestCoversNonResourceURLsWithOtherFieldsFailure(t *testing.T) {
escalationTest{
ownerRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"builds"}},
},
servantRules: []rbac.PolicyRule{
{APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"builds"}, NonResourceURLs: []string{"/apis"}},
},
expectedCovered: false,
expectedUncoveredRules: []rbac.PolicyRule{{NonResourceURLs: []string{"/apis"}, Verbs: []string{"get"}}},
}.test(t)
}
func (test escalationTest) test(t *testing.T) {
actualCovered, actualUncoveredRules := Covers(test.ownerRules, test.servantRules)
if actualCovered != test.expectedCovered {
t.Errorf("expected %v, but got %v", test.expectedCovered, actualCovered)
}
if !rulesMatch(test.expectedUncoveredRules, actualUncoveredRules) {
t.Errorf("expected %v, but got %v", test.expectedUncoveredRules, actualUncoveredRules)
}
}
func rulesMatch(expectedRules, actualRules []rbac.PolicyRule) bool {
if len(expectedRules) != len(actualRules) {
return false
}
for _, expectedRule := range expectedRules {
found := false
for _, actualRule := range actualRules {
if reflect.DeepEqual(expectedRule, actualRule) {
found = true
break
}
}
if !found {
return false
}
}
return true
}

View file

@ -0,0 +1,254 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"errors"
"fmt"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
apierrors "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/serviceaccount"
utilerrors "k8s.io/kubernetes/pkg/util/errors"
)
type AuthorizationRuleResolver interface {
// GetRoleReferenceRules attempts to resolve the role reference of a RoleBinding or ClusterRoleBinding. The passed namespace should be the namepsace
// of the role binding, the empty string if a cluster role binding.
GetRoleReferenceRules(roleRef rbac.RoleRef, namespace string) ([]rbac.PolicyRule, error)
// RulesFor returns the list of rules that apply to a given user in a given namespace and error. If an error is returned, the slice of
// PolicyRules may not be complete, but it contains all retrievable rules. This is done because policy rules are purely additive and policy determinations
// can be made on the basis of those rules that are found.
RulesFor(user user.Info, namespace string) ([]rbac.PolicyRule, error)
}
// ConfirmNoEscalation determines if the roles for a given user in a given namespace encompass the provided role.
func ConfirmNoEscalation(ctx api.Context, ruleResolver AuthorizationRuleResolver, rules []rbac.PolicyRule) error {
ruleResolutionErrors := []error{}
user, ok := api.UserFrom(ctx)
if !ok {
return fmt.Errorf("no user on context")
}
namespace, _ := api.NamespaceFrom(ctx)
ownerRules, err := ruleResolver.RulesFor(user, namespace)
if err != nil {
// As per AuthorizationRuleResolver contract, this may return a non fatal error with an incomplete list of policies. Log the error and continue.
glog.V(1).Infof("non-fatal error getting local rules for %v: %v", user, err)
ruleResolutionErrors = append(ruleResolutionErrors, err)
}
ownerRightsCover, missingRights := Covers(ownerRules, rules)
if !ownerRightsCover {
user, _ := api.UserFrom(ctx)
return apierrors.NewUnauthorized(fmt.Sprintf("attempt to grant extra privileges: %v user=%v ownerrules=%v ruleResolutionErrors=%v", missingRights, user, ownerRules, ruleResolutionErrors))
}
return nil
}
type DefaultRuleResolver struct {
roleGetter RoleGetter
roleBindingLister RoleBindingLister
clusterRoleGetter ClusterRoleGetter
clusterRoleBindingLister ClusterRoleBindingLister
}
func NewDefaultRuleResolver(roleGetter RoleGetter, roleBindingLister RoleBindingLister, clusterRoleGetter ClusterRoleGetter, clusterRoleBindingLister ClusterRoleBindingLister) *DefaultRuleResolver {
return &DefaultRuleResolver{roleGetter, roleBindingLister, clusterRoleGetter, clusterRoleBindingLister}
}
type RoleGetter interface {
GetRole(namespace, name string) (*rbac.Role, error)
}
type RoleBindingLister interface {
ListRoleBindings(namespace string) ([]*rbac.RoleBinding, error)
}
type ClusterRoleGetter interface {
GetClusterRole(name string) (*rbac.ClusterRole, error)
}
type ClusterRoleBindingLister interface {
ListClusterRoleBindings() ([]*rbac.ClusterRoleBinding, error)
}
func (r *DefaultRuleResolver) RulesFor(user user.Info, namespace string) ([]rbac.PolicyRule, error) {
policyRules := []rbac.PolicyRule{}
errorlist := []error{}
if clusterRoleBindings, err := r.clusterRoleBindingLister.ListClusterRoleBindings(); err != nil {
errorlist = append(errorlist, err)
} else {
for _, clusterRoleBinding := range clusterRoleBindings {
if !appliesTo(user, clusterRoleBinding.Subjects, "") {
continue
}
rules, err := r.GetRoleReferenceRules(clusterRoleBinding.RoleRef, "")
if err != nil {
errorlist = append(errorlist, err)
continue
}
policyRules = append(policyRules, rules...)
}
}
if len(namespace) > 0 {
if roleBindings, err := r.roleBindingLister.ListRoleBindings(namespace); err != nil {
errorlist = append(errorlist, err)
} else {
for _, roleBinding := range roleBindings {
if !appliesTo(user, roleBinding.Subjects, namespace) {
continue
}
rules, err := r.GetRoleReferenceRules(roleBinding.RoleRef, namespace)
if err != nil {
errorlist = append(errorlist, err)
continue
}
policyRules = append(policyRules, rules...)
}
}
}
return policyRules, utilerrors.NewAggregate(errorlist)
}
// GetRoleReferenceRules attempts to resolve the RoleBinding or ClusterRoleBinding.
func (r *DefaultRuleResolver) GetRoleReferenceRules(roleRef rbac.RoleRef, bindingNamespace string) ([]rbac.PolicyRule, error) {
switch kind := rbac.RoleRefGroupKind(roleRef); kind {
case rbac.Kind("Role"):
role, err := r.roleGetter.GetRole(bindingNamespace, roleRef.Name)
if err != nil {
return nil, err
}
return role.Rules, nil
case rbac.Kind("ClusterRole"):
clusterRole, err := r.clusterRoleGetter.GetClusterRole(roleRef.Name)
if err != nil {
return nil, err
}
return clusterRole.Rules, nil
default:
return nil, fmt.Errorf("unsupported role reference kind: %q", kind)
}
}
func appliesTo(user user.Info, bindingSubjects []rbac.Subject, namespace string) bool {
for _, bindingSubject := range bindingSubjects {
if appliesToUser(user, bindingSubject, namespace) {
return true
}
}
return false
}
func appliesToUser(user user.Info, subject rbac.Subject, namespace string) bool {
switch subject.Kind {
case rbac.UserKind:
return subject.Name == rbac.UserAll || user.GetName() == subject.Name
case rbac.GroupKind:
return has(user.GetGroups(), subject.Name)
case rbac.ServiceAccountKind:
// default the namespace to namespace we're working in if its available. This allows rolebindings that reference
// SAs in th local namespace to avoid having to qualify them.
saNamespace := namespace
if len(subject.Namespace) > 0 {
saNamespace = subject.Namespace
}
if len(saNamespace) == 0 {
return false
}
return serviceaccount.MakeUsername(saNamespace, subject.Name) == user.GetName()
default:
return false
}
}
// NewTestRuleResolver returns a rule resolver from lists of role objects.
func NewTestRuleResolver(roles []*rbac.Role, roleBindings []*rbac.RoleBinding, clusterRoles []*rbac.ClusterRole, clusterRoleBindings []*rbac.ClusterRoleBinding) (AuthorizationRuleResolver, *StaticRoles) {
r := StaticRoles{
roles: roles,
roleBindings: roleBindings,
clusterRoles: clusterRoles,
clusterRoleBindings: clusterRoleBindings,
}
return newMockRuleResolver(&r), &r
}
func newMockRuleResolver(r *StaticRoles) AuthorizationRuleResolver {
return NewDefaultRuleResolver(r, r, r, r)
}
// StaticRoles is a rule resolver that resolves from lists of role objects.
type StaticRoles struct {
roles []*rbac.Role
roleBindings []*rbac.RoleBinding
clusterRoles []*rbac.ClusterRole
clusterRoleBindings []*rbac.ClusterRoleBinding
}
func (r *StaticRoles) GetRole(namespace, name string) (*rbac.Role, error) {
if len(namespace) == 0 {
return nil, errors.New("must provide namespace when getting role")
}
for _, role := range r.roles {
if role.Namespace == namespace && role.Name == name {
return role, nil
}
}
return nil, errors.New("role not found")
}
func (r *StaticRoles) GetClusterRole(name string) (*rbac.ClusterRole, error) {
for _, clusterRole := range r.clusterRoles {
if clusterRole.Name == name {
return clusterRole, nil
}
}
return nil, errors.New("role not found")
}
func (r *StaticRoles) ListRoleBindings(namespace string) ([]*rbac.RoleBinding, error) {
if len(namespace) == 0 {
return nil, errors.New("must provide namespace when listing role bindings")
}
roleBindingList := []*rbac.RoleBinding{}
for _, roleBinding := range r.roleBindings {
if roleBinding.Namespace != namespace {
continue
}
// TODO(ericchiang): need to implement label selectors?
roleBindingList = append(roleBindingList, roleBinding)
}
return roleBindingList, nil
}
func (r *StaticRoles) ListClusterRoleBindings() ([]*rbac.ClusterRoleBinding, error) {
return r.clusterRoleBindings, nil
}

View file

@ -0,0 +1,246 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"hash/fnv"
"io"
"reflect"
"sort"
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/util/diff"
)
// compute a hash of a policy rule so we can sort in a deterministic order
func hashOf(p rbac.PolicyRule) string {
hash := fnv.New32()
writeStrings := func(slis ...[]string) {
for _, sli := range slis {
for _, s := range sli {
io.WriteString(hash, s)
}
}
}
writeStrings(p.Verbs, p.APIGroups, p.Resources, p.ResourceNames, p.NonResourceURLs)
return string(hash.Sum(nil))
}
// byHash sorts a set of policy rules by a hash of its fields
type byHash []rbac.PolicyRule
func (b byHash) Len() int { return len(b) }
func (b byHash) Less(i, j int) bool { return hashOf(b[i]) < hashOf(b[j]) }
func (b byHash) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func TestDefaultRuleResolver(t *testing.T) {
ruleReadPods := rbac.PolicyRule{
Verbs: []string{"GET", "WATCH"},
APIGroups: []string{"v1"},
Resources: []string{"pods"},
}
ruleReadServices := rbac.PolicyRule{
Verbs: []string{"GET", "WATCH"},
APIGroups: []string{"v1"},
Resources: []string{"services"},
}
ruleWriteNodes := rbac.PolicyRule{
Verbs: []string{"PUT", "CREATE", "UPDATE"},
APIGroups: []string{"v1"},
Resources: []string{"nodes"},
}
ruleAdmin := rbac.PolicyRule{
Verbs: []string{"*"},
APIGroups: []string{"*"},
Resources: []string{"*"},
}
staticRoles1 := StaticRoles{
roles: []*rbac.Role{
{
ObjectMeta: api.ObjectMeta{Namespace: "namespace1", Name: "readthings"},
Rules: []rbac.PolicyRule{ruleReadPods, ruleReadServices},
},
},
clusterRoles: []*rbac.ClusterRole{
{
ObjectMeta: api.ObjectMeta{Name: "cluster-admin"},
Rules: []rbac.PolicyRule{ruleAdmin},
},
{
ObjectMeta: api.ObjectMeta{Name: "write-nodes"},
Rules: []rbac.PolicyRule{ruleWriteNodes},
},
},
roleBindings: []*rbac.RoleBinding{
{
ObjectMeta: api.ObjectMeta{Namespace: "namespace1"},
Subjects: []rbac.Subject{
{Kind: rbac.UserKind, Name: "foobar"},
{Kind: rbac.GroupKind, Name: "group1"},
},
RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "Role", Name: "readthings"},
},
},
clusterRoleBindings: []*rbac.ClusterRoleBinding{
{
Subjects: []rbac.Subject{
{Kind: rbac.UserKind, Name: "admin"},
{Kind: rbac.GroupKind, Name: "admin"},
},
RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "ClusterRole", Name: "cluster-admin"},
},
},
}
tests := []struct {
StaticRoles
// For a given context, what are the rules that apply?
user user.Info
namespace string
effectiveRules []rbac.PolicyRule
}{
{
StaticRoles: staticRoles1,
user: &user.DefaultInfo{Name: "foobar"},
namespace: "namespace1",
effectiveRules: []rbac.PolicyRule{ruleReadPods, ruleReadServices},
},
{
StaticRoles: staticRoles1,
user: &user.DefaultInfo{Name: "foobar"},
namespace: "namespace2",
effectiveRules: []rbac.PolicyRule{},
},
{
StaticRoles: staticRoles1,
// Same as above but without a namespace. Only cluster rules should apply.
user: &user.DefaultInfo{Name: "foobar", Groups: []string{"admin"}},
effectiveRules: []rbac.PolicyRule{ruleAdmin},
},
{
StaticRoles: staticRoles1,
user: &user.DefaultInfo{},
effectiveRules: []rbac.PolicyRule{},
},
}
for i, tc := range tests {
ruleResolver := newMockRuleResolver(&tc.StaticRoles)
rules, err := ruleResolver.RulesFor(tc.user, tc.namespace)
if err != nil {
t.Errorf("case %d: GetEffectivePolicyRules(context)=%v", i, err)
continue
}
// Sort for deep equals
sort.Sort(byHash(rules))
sort.Sort(byHash(tc.effectiveRules))
if !reflect.DeepEqual(rules, tc.effectiveRules) {
ruleDiff := diff.ObjectDiff(rules, tc.effectiveRules)
t.Errorf("case %d: %s", i, ruleDiff)
}
}
}
func TestAppliesTo(t *testing.T) {
tests := []struct {
subjects []rbac.Subject
user user.Info
namespace string
appliesTo bool
testCase string
}{
{
subjects: []rbac.Subject{
{Kind: rbac.UserKind, Name: "foobar"},
},
user: &user.DefaultInfo{Name: "foobar"},
appliesTo: true,
testCase: "single subject that matches username",
},
{
subjects: []rbac.Subject{
{Kind: rbac.UserKind, Name: "barfoo"},
{Kind: rbac.UserKind, Name: "foobar"},
},
user: &user.DefaultInfo{Name: "foobar"},
appliesTo: true,
testCase: "multiple subjects, one that matches username",
},
{
subjects: []rbac.Subject{
{Kind: rbac.UserKind, Name: "barfoo"},
{Kind: rbac.UserKind, Name: "foobar"},
},
user: &user.DefaultInfo{Name: "zimzam"},
appliesTo: false,
testCase: "multiple subjects, none that match username",
},
{
subjects: []rbac.Subject{
{Kind: rbac.UserKind, Name: "barfoo"},
{Kind: rbac.GroupKind, Name: "foobar"},
},
user: &user.DefaultInfo{Name: "zimzam", Groups: []string{"foobar"}},
appliesTo: true,
testCase: "multiple subjects, one that match group",
},
{
subjects: []rbac.Subject{
{Kind: rbac.UserKind, Name: "barfoo"},
{Kind: rbac.GroupKind, Name: "foobar"},
},
user: &user.DefaultInfo{Name: "zimzam", Groups: []string{"foobar"}},
namespace: "namespace1",
appliesTo: true,
testCase: "multiple subjects, one that match group, should ignore namespace",
},
{
subjects: []rbac.Subject{
{Kind: rbac.UserKind, Name: "barfoo"},
{Kind: rbac.GroupKind, Name: "foobar"},
{Kind: rbac.ServiceAccountKind, Namespace: "kube-system", Name: "default"},
},
user: &user.DefaultInfo{Name: "system:serviceaccount:kube-system:default"},
namespace: "default",
appliesTo: true,
testCase: "multiple subjects with a service account that matches",
},
{
subjects: []rbac.Subject{
{Kind: rbac.UserKind, Name: "*"},
},
user: &user.DefaultInfo{Name: "foobar"},
namespace: "default",
appliesTo: true,
testCase: "multiple subjects with a service account that matches",
},
}
for _, tc := range tests {
got := appliesTo(tc.user, tc.subjects, tc.namespace)
if got != tc.appliesTo {
t.Errorf("case %q want appliesTo=%t, got appliesTo=%t", tc.testCase, tc.appliesTo, got)
}
}
}

View file

@ -0,0 +1,225 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package validation
import (
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/api/validation/path"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/util/validation/field"
)
// Minimal validation of names for roles and bindings. Identical to the validation for Openshift. See:
// * https://github.com/kubernetes/kubernetes/blob/60db50/pkg/api/validation/name.go
// * https://github.com/openshift/origin/blob/388478/pkg/api/helpers.go
func minimalNameRequirements(name string, prefix bool) []string {
return path.IsValidPathSegmentName(name)
}
func ValidateRole(role *rbac.Role) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, validation.ValidateObjectMeta(&role.ObjectMeta, true, minimalNameRequirements, field.NewPath("metadata"))...)
for i, rule := range role.Rules {
if err := validatePolicyRule(rule, true, field.NewPath("rules").Index(i)); err != nil {
allErrs = append(allErrs, err...)
}
}
if len(allErrs) != 0 {
return allErrs
}
return nil
}
func ValidateRoleUpdate(role *rbac.Role, oldRole *rbac.Role) field.ErrorList {
allErrs := ValidateRole(role)
allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(&role.ObjectMeta, &oldRole.ObjectMeta, field.NewPath("metadata"))...)
return allErrs
}
func ValidateClusterRole(role *rbac.ClusterRole) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, validation.ValidateObjectMeta(&role.ObjectMeta, false, minimalNameRequirements, field.NewPath("metadata"))...)
for i, rule := range role.Rules {
if err := validatePolicyRule(rule, false, field.NewPath("rules").Index(i)); err != nil {
allErrs = append(allErrs, err...)
}
}
if len(allErrs) != 0 {
return allErrs
}
return nil
}
func ValidateClusterRoleUpdate(role *rbac.ClusterRole, oldRole *rbac.ClusterRole) field.ErrorList {
allErrs := ValidateClusterRole(role)
allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(&role.ObjectMeta, &oldRole.ObjectMeta, field.NewPath("metadata"))...)
return allErrs
}
func validatePolicyRule(rule rbac.PolicyRule, isNamespaced bool, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(rule.Verbs) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("verbs"), "verbs must contain at least one value"))
}
if len(rule.NonResourceURLs) > 0 {
if isNamespaced {
allErrs = append(allErrs, field.Invalid(fldPath.Child("nonResourceURLs"), rule.NonResourceURLs, "namespaced rules cannot apply to non-resource URLs"))
}
if len(rule.APIGroups) > 0 || len(rule.Resources) > 0 || len(rule.ResourceNames) > 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("nonResourceURLs"), rule.NonResourceURLs, "rules cannot apply to both regular resources and non-resource URLs"))
}
return allErrs
}
if len(rule.APIGroups) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("apiGroups"), "resource rules must supply at least one api group"))
}
if len(rule.Resources) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("resources"), "resource rules must supply at least one resource"))
}
return allErrs
}
func ValidateRoleBinding(roleBinding *rbac.RoleBinding) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, validation.ValidateObjectMeta(&roleBinding.ObjectMeta, true, minimalNameRequirements, field.NewPath("metadata"))...)
// TODO allow multiple API groups. For now, restrict to one, but I can envision other experimental roles in other groups taking
// advantage of the binding infrastructure
if roleBinding.RoleRef.APIGroup != rbac.GroupName {
allErrs = append(allErrs, field.NotSupported(field.NewPath("roleRef", "apiGroup"), roleBinding.RoleRef.APIGroup, []string{rbac.GroupName}))
}
switch roleBinding.RoleRef.Kind {
case "Role", "ClusterRole":
default:
allErrs = append(allErrs, field.NotSupported(field.NewPath("roleRef", "kind"), roleBinding.RoleRef.Kind, []string{"Role", "ClusterRole"}))
}
if len(roleBinding.RoleRef.Name) == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), ""))
} else {
for _, msg := range minimalNameRequirements(roleBinding.RoleRef.Name, false) {
allErrs = append(allErrs, field.Invalid(field.NewPath("roleRef", "name"), roleBinding.RoleRef.Name, msg))
}
}
subjectsPath := field.NewPath("subjects")
for i, subject := range roleBinding.Subjects {
allErrs = append(allErrs, validateRoleBindingSubject(subject, true, subjectsPath.Index(i))...)
}
return allErrs
}
func ValidateRoleBindingUpdate(roleBinding *rbac.RoleBinding, oldRoleBinding *rbac.RoleBinding) field.ErrorList {
allErrs := ValidateRoleBinding(roleBinding)
allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(&roleBinding.ObjectMeta, &oldRoleBinding.ObjectMeta, field.NewPath("metadata"))...)
if oldRoleBinding.RoleRef != roleBinding.RoleRef {
allErrs = append(allErrs, field.Invalid(field.NewPath("roleRef"), roleBinding.RoleRef, "cannot change roleRef"))
}
return allErrs
}
func ValidateClusterRoleBinding(roleBinding *rbac.ClusterRoleBinding) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, validation.ValidateObjectMeta(&roleBinding.ObjectMeta, false, minimalNameRequirements, field.NewPath("metadata"))...)
// TODO allow multiple API groups. For now, restrict to one, but I can envision other experimental roles in other groups taking
// advantage of the binding infrastructure
if roleBinding.RoleRef.APIGroup != rbac.GroupName {
allErrs = append(allErrs, field.NotSupported(field.NewPath("roleRef", "apiGroup"), roleBinding.RoleRef.APIGroup, []string{rbac.GroupName}))
}
switch roleBinding.RoleRef.Kind {
case "ClusterRole":
default:
allErrs = append(allErrs, field.NotSupported(field.NewPath("roleRef", "kind"), roleBinding.RoleRef.Kind, []string{"ClusterRole"}))
}
if len(roleBinding.RoleRef.Name) == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("roleRef", "name"), ""))
} else {
for _, msg := range minimalNameRequirements(roleBinding.RoleRef.Name, false) {
allErrs = append(allErrs, field.Invalid(field.NewPath("roleRef", "name"), roleBinding.RoleRef.Name, msg))
}
}
subjectsPath := field.NewPath("subjects")
for i, subject := range roleBinding.Subjects {
allErrs = append(allErrs, validateRoleBindingSubject(subject, false, subjectsPath.Index(i))...)
}
return allErrs
}
func ValidateClusterRoleBindingUpdate(roleBinding *rbac.ClusterRoleBinding, oldRoleBinding *rbac.ClusterRoleBinding) field.ErrorList {
allErrs := ValidateClusterRoleBinding(roleBinding)
allErrs = append(allErrs, validation.ValidateObjectMetaUpdate(&roleBinding.ObjectMeta, &oldRoleBinding.ObjectMeta, field.NewPath("metadata"))...)
if oldRoleBinding.RoleRef != roleBinding.RoleRef {
allErrs = append(allErrs, field.Invalid(field.NewPath("roleRef"), roleBinding.RoleRef, "cannot change roleRef"))
}
return allErrs
}
func validateRoleBindingSubject(subject rbac.Subject, isNamespaced bool, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if len(subject.Name) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("name"), ""))
}
switch subject.Kind {
case rbac.ServiceAccountKind:
if len(subject.Name) > 0 {
for _, msg := range validation.ValidateServiceAccountName(subject.Name, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, msg))
}
}
if !isNamespaced && len(subject.Namespace) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), ""))
}
case rbac.UserKind:
// TODO(ericchiang): What other restrictions on user name are there?
if len(subject.Name) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, "user name cannot be empty"))
}
case rbac.GroupKind:
// TODO(ericchiang): What other restrictions on group name are there?
if len(subject.Name) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), subject.Name, "group name cannot be empty"))
}
default:
allErrs = append(allErrs, field.NotSupported(fldPath.Child("kind"), subject.Kind, []string{rbac.ServiceAccountKind, rbac.UserKind, rbac.GroupKind}))
}
return allErrs
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,297 @@
// +build !ignore_autogenerated
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
package rbac
import (
api "k8s.io/kubernetes/pkg/api"
conversion "k8s.io/kubernetes/pkg/conversion"
runtime "k8s.io/kubernetes/pkg/runtime"
reflect "reflect"
)
func init() {
SchemeBuilder.Register(RegisterDeepCopies)
}
// RegisterDeepCopies adds deep-copy functions to the given scheme. Public
// to allow building arbitrary schemes.
func RegisterDeepCopies(scheme *runtime.Scheme) error {
return scheme.AddGeneratedDeepCopyFuncs(
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_rbac_ClusterRole, InType: reflect.TypeOf(&ClusterRole{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_rbac_ClusterRoleBinding, InType: reflect.TypeOf(&ClusterRoleBinding{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_rbac_ClusterRoleBindingList, InType: reflect.TypeOf(&ClusterRoleBindingList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_rbac_ClusterRoleList, InType: reflect.TypeOf(&ClusterRoleList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_rbac_PolicyRule, InType: reflect.TypeOf(&PolicyRule{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_rbac_Role, InType: reflect.TypeOf(&Role{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_rbac_RoleBinding, InType: reflect.TypeOf(&RoleBinding{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_rbac_RoleBindingList, InType: reflect.TypeOf(&RoleBindingList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_rbac_RoleList, InType: reflect.TypeOf(&RoleList{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_rbac_RoleRef, InType: reflect.TypeOf(&RoleRef{})},
conversion.GeneratedDeepCopyFunc{Fn: DeepCopy_rbac_Subject, InType: reflect.TypeOf(&Subject{})},
)
}
func DeepCopy_rbac_ClusterRole(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*ClusterRole)
out := out.(*ClusterRole)
out.TypeMeta = in.TypeMeta
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]PolicyRule, len(*in))
for i := range *in {
if err := DeepCopy_rbac_PolicyRule(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Rules = nil
}
return nil
}
}
func DeepCopy_rbac_ClusterRoleBinding(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*ClusterRoleBinding)
out := out.(*ClusterRoleBinding)
out.TypeMeta = in.TypeMeta
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if in.Subjects != nil {
in, out := &in.Subjects, &out.Subjects
*out = make([]Subject, len(*in))
for i := range *in {
(*out)[i] = (*in)[i]
}
} else {
out.Subjects = nil
}
out.RoleRef = in.RoleRef
return nil
}
}
func DeepCopy_rbac_ClusterRoleBindingList(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*ClusterRoleBindingList)
out := out.(*ClusterRoleBindingList)
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ClusterRoleBinding, len(*in))
for i := range *in {
if err := DeepCopy_rbac_ClusterRoleBinding(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
}
func DeepCopy_rbac_ClusterRoleList(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*ClusterRoleList)
out := out.(*ClusterRoleList)
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ClusterRole, len(*in))
for i := range *in {
if err := DeepCopy_rbac_ClusterRole(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
}
func DeepCopy_rbac_PolicyRule(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*PolicyRule)
out := out.(*PolicyRule)
if in.Verbs != nil {
in, out := &in.Verbs, &out.Verbs
*out = make([]string, len(*in))
copy(*out, *in)
} else {
out.Verbs = nil
}
if in.AttributeRestrictions == nil {
out.AttributeRestrictions = nil
} else if newVal, err := c.DeepCopy(&in.AttributeRestrictions); err != nil {
return err
} else {
out.AttributeRestrictions = *newVal.(*runtime.Object)
}
if in.APIGroups != nil {
in, out := &in.APIGroups, &out.APIGroups
*out = make([]string, len(*in))
copy(*out, *in)
} else {
out.APIGroups = nil
}
if in.Resources != nil {
in, out := &in.Resources, &out.Resources
*out = make([]string, len(*in))
copy(*out, *in)
} else {
out.Resources = nil
}
if in.ResourceNames != nil {
in, out := &in.ResourceNames, &out.ResourceNames
*out = make([]string, len(*in))
copy(*out, *in)
} else {
out.ResourceNames = nil
}
if in.NonResourceURLs != nil {
in, out := &in.NonResourceURLs, &out.NonResourceURLs
*out = make([]string, len(*in))
copy(*out, *in)
} else {
out.NonResourceURLs = nil
}
return nil
}
}
func DeepCopy_rbac_Role(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*Role)
out := out.(*Role)
out.TypeMeta = in.TypeMeta
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]PolicyRule, len(*in))
for i := range *in {
if err := DeepCopy_rbac_PolicyRule(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Rules = nil
}
return nil
}
}
func DeepCopy_rbac_RoleBinding(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*RoleBinding)
out := out.(*RoleBinding)
out.TypeMeta = in.TypeMeta
if err := api.DeepCopy_api_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, c); err != nil {
return err
}
if in.Subjects != nil {
in, out := &in.Subjects, &out.Subjects
*out = make([]Subject, len(*in))
for i := range *in {
(*out)[i] = (*in)[i]
}
} else {
out.Subjects = nil
}
out.RoleRef = in.RoleRef
return nil
}
}
func DeepCopy_rbac_RoleBindingList(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*RoleBindingList)
out := out.(*RoleBindingList)
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]RoleBinding, len(*in))
for i := range *in {
if err := DeepCopy_rbac_RoleBinding(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
}
func DeepCopy_rbac_RoleList(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*RoleList)
out := out.(*RoleList)
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Role, len(*in))
for i := range *in {
if err := DeepCopy_rbac_Role(&(*in)[i], &(*out)[i], c); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
}
func DeepCopy_rbac_RoleRef(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*RoleRef)
out := out.(*RoleRef)
out.APIGroup = in.APIGroup
out.Kind = in.Kind
out.Name = in.Name
return nil
}
}
func DeepCopy_rbac_Subject(in interface{}, out interface{}, c *conversion.Cloner) error {
{
in := in.(*Subject)
out := out.(*Subject)
out.Kind = in.Kind
out.APIVersion = in.APIVersion
out.Name = in.Name
out.Namespace = in.Namespace
return nil
}
}