Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
6f312f14
Commit
6f312f14
authored
May 25, 2016
by
Eric Chiang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pkg/registry: add rbac storage
parent
e3604e25
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
1601 additions
and
0 deletions
+1601
-0
cachesize.go
pkg/registry/cachesize/cachesize.go
+8
-0
doc.go
pkg/registry/clusterrole/doc.go
+19
-0
etcd.go
pkg/registry/clusterrole/etcd/etcd.go
+76
-0
storage.go
pkg/registry/clusterrole/policybased/storage.go
+100
-0
registry.go
pkg/registry/clusterrole/registry.go
+81
-0
strategy.go
pkg/registry/clusterrole/strategy.go
+119
-0
doc.go
pkg/registry/clusterrolebinding/doc.go
+19
-0
etcd.go
pkg/registry/clusterrolebinding/etcd/etcd.go
+76
-0
storage.go
pkg/registry/clusterrolebinding/policybased/storage.go
+106
-0
registry.go
pkg/registry/clusterrolebinding/registry.go
+81
-0
strategy.go
pkg/registry/clusterrolebinding/strategy.go
+119
-0
doc.go
pkg/registry/role/doc.go
+19
-0
etcd.go
pkg/registry/role/etcd/etcd.go
+76
-0
storage.go
pkg/registry/role/policybased/storage.go
+100
-0
registry.go
pkg/registry/role/registry.go
+81
-0
strategy.go
pkg/registry/role/strategy.go
+119
-0
doc.go
pkg/registry/rolebinding/doc.go
+19
-0
etcd.go
pkg/registry/rolebinding/etcd/etcd.go
+76
-0
storage.go
pkg/registry/rolebinding/policybased/storage.go
+106
-0
registry.go
pkg/registry/rolebinding/registry.go
+82
-0
strategy.go
pkg/registry/rolebinding/strategy.go
+119
-0
No files found.
pkg/registry/cachesize/cachesize.go
View file @
6f312f14
...
...
@@ -28,6 +28,8 @@ import (
type
Resource
string
const
(
ClusterRoles
Resource
=
"clusterroles"
ClusterRoleBindings
Resource
=
"clusterrolebindings"
Controllers
Resource
=
"controllers"
Daemonsets
Resource
=
"daemonsets"
Deployments
Resource
=
"deployments"
...
...
@@ -48,6 +50,8 @@ const (
Replicasets
Resource
=
"replicasets"
ResourceQuotas
Resource
=
"resourcequotas"
ScheduledJobs
Resource
=
"scheduledjobs"
Roles
Resource
=
"roles"
RoleBindings
Resource
=
"rolebindings"
Secrets
Resource
=
"secrets"
ServiceAccounts
Resource
=
"serviceaccounts"
Services
Resource
=
"services"
...
...
@@ -57,6 +61,8 @@ var watchCacheSizes map[Resource]int
func
init
()
{
watchCacheSizes
=
make
(
map
[
Resource
]
int
)
watchCacheSizes
[
ClusterRoles
]
=
100
watchCacheSizes
[
ClusterRoleBindings
]
=
100
watchCacheSizes
[
Controllers
]
=
100
watchCacheSizes
[
Daemonsets
]
=
100
watchCacheSizes
[
Deployments
]
=
100
...
...
@@ -77,6 +83,8 @@ func init() {
watchCacheSizes
[
Replicasets
]
=
100
watchCacheSizes
[
ResourceQuotas
]
=
100
watchCacheSizes
[
ScheduledJobs
]
=
100
watchCacheSizes
[
Roles
]
=
100
watchCacheSizes
[
RoleBindings
]
=
100
watchCacheSizes
[
Secrets
]
=
100
watchCacheSizes
[
ServiceAccounts
]
=
100
watchCacheSizes
[
Services
]
=
100
...
...
pkg/registry/clusterrole/doc.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 certificates provides Registry interface and its RESTStorage
// implementation for storing ClusterRole objects.
package
clusterrole
pkg/registry/clusterrole/etcd/etcd.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
etcd
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/clusterrole"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime"
)
// REST implements a RESTStorage for ClusterRole against etcd
type
REST
struct
{
*
registry
.
Store
}
// NewREST returns a RESTStorage object that will work against ClusterRole objects.
func
NewREST
(
opts
generic
.
RESTOptions
)
*
REST
{
prefix
:=
"/clusterroles"
newListFunc
:=
func
()
runtime
.
Object
{
return
&
rbac
.
ClusterRoleList
{}
}
storageInterface
:=
opts
.
Decorator
(
opts
.
Storage
,
cachesize
.
GetWatchCacheSizeByResource
(
cachesize
.
ClusterRoles
),
&
rbac
.
ClusterRole
{},
prefix
,
clusterrole
.
Strategy
,
newListFunc
,
)
store
:=
&
registry
.
Store
{
NewFunc
:
func
()
runtime
.
Object
{
return
&
rbac
.
ClusterRole
{}
},
NewListFunc
:
newListFunc
,
KeyRootFunc
:
func
(
ctx
api
.
Context
)
string
{
return
registry
.
NamespaceKeyRootFunc
(
ctx
,
prefix
)
},
KeyFunc
:
func
(
ctx
api
.
Context
,
id
string
)
(
string
,
error
)
{
return
registry
.
NoNamespaceKeyFunc
(
ctx
,
prefix
,
id
)
},
ObjectNameFunc
:
func
(
obj
runtime
.
Object
)
(
string
,
error
)
{
return
obj
.
(
*
rbac
.
ClusterRole
)
.
Name
,
nil
},
PredicateFunc
:
func
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
clusterrole
.
Matcher
(
label
,
field
)
},
QualifiedResource
:
rbac
.
Resource
(
"clusterroles"
),
DeleteCollectionWorkers
:
opts
.
DeleteCollectionWorkers
,
CreateStrategy
:
clusterrole
.
Strategy
,
UpdateStrategy
:
clusterrole
.
Strategy
,
DeleteStrategy
:
clusterrole
.
Strategy
,
Storage
:
storageInterface
,
}
return
&
REST
{
store
}
}
pkg/registry/clusterrole/policybased/storage.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 policybased implements a standard storage for ClusterRole that prevents privilege escalation.
package
policybased
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
"k8s.io/kubernetes/pkg/runtime"
)
var
groupResource
=
rbac
.
Resource
(
"clusterroles"
)
type
Storage
struct
{
rest
.
StandardStorage
ruleResolver
validation
.
AuthorizationRuleResolver
// user which skips privilege escalation checks
superUser
string
}
func
NewStorage
(
s
rest
.
StandardStorage
,
ruleResolver
validation
.
AuthorizationRuleResolver
,
superUser
string
)
*
Storage
{
return
&
Storage
{
s
,
ruleResolver
,
superUser
}
}
func
(
s
*
Storage
)
Create
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
if
user
,
ok
:=
api
.
UserFrom
(
ctx
);
ok
{
if
s
.
superUser
!=
""
&&
user
.
GetName
()
==
s
.
superUser
{
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
)
}
}
clusterRole
:=
obj
.
(
*
rbac
.
ClusterRole
)
rules
:=
clusterRole
.
Rules
if
err
:=
validation
.
ConfirmNoEscalation
(
ctx
,
s
.
ruleResolver
,
rules
);
err
!=
nil
{
return
nil
,
errors
.
NewForbidden
(
groupResource
,
clusterRole
.
Name
,
err
)
}
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
)
}
func
(
s
*
Storage
)
Update
(
ctx
api
.
Context
,
name
string
,
obj
rest
.
UpdatedObjectInfo
)
(
runtime
.
Object
,
bool
,
error
)
{
if
user
,
ok
:=
api
.
UserFrom
(
ctx
);
ok
{
if
s
.
superUser
!=
""
&&
user
.
GetName
()
==
s
.
superUser
{
return
s
.
StandardStorage
.
Update
(
ctx
,
name
,
obj
)
}
}
nonEscalatingInfo
:=
wrapUpdatedObjectInfo
(
obj
,
func
(
ctx
api
.
Context
,
obj
runtime
.
Object
,
oldObj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
clusterRole
:=
obj
.
(
*
rbac
.
ClusterRole
)
rules
:=
clusterRole
.
Rules
if
err
:=
validation
.
ConfirmNoEscalation
(
ctx
,
s
.
ruleResolver
,
rules
);
err
!=
nil
{
return
nil
,
errors
.
NewForbidden
(
groupResource
,
clusterRole
.
Name
,
err
)
}
return
obj
,
nil
})
return
s
.
StandardStorage
.
Update
(
ctx
,
name
,
nonEscalatingInfo
)
}
// TODO(ericchiang): This logic is copied from #26240. Replace with once that PR is merged into master.
type
wrappedUpdatedObjectInfo
struct
{
objInfo
rest
.
UpdatedObjectInfo
transformFunc
rest
.
TransformFunc
}
func
wrapUpdatedObjectInfo
(
objInfo
rest
.
UpdatedObjectInfo
,
transformFunc
rest
.
TransformFunc
)
rest
.
UpdatedObjectInfo
{
return
&
wrappedUpdatedObjectInfo
{
objInfo
,
transformFunc
}
}
func
(
i
*
wrappedUpdatedObjectInfo
)
Preconditions
()
*
api
.
Preconditions
{
return
i
.
objInfo
.
Preconditions
()
}
func
(
i
*
wrappedUpdatedObjectInfo
)
UpdatedObject
(
ctx
api
.
Context
,
oldObj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
obj
,
err
:=
i
.
objInfo
.
UpdatedObject
(
ctx
,
oldObj
)
if
err
!=
nil
{
return
obj
,
err
}
return
i
.
transformFunc
(
ctx
,
obj
,
oldObj
)
}
pkg/registry/clusterrole/registry.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
clusterrole
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/watch"
)
// Registry is an interface for things that know how to store ClusterRoles.
type
Registry
interface
{
ListClusterRoles
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
*
rbac
.
ClusterRoleList
,
error
)
CreateClusterRole
(
ctx
api
.
Context
,
clusterRole
*
rbac
.
ClusterRole
)
error
UpdateClusterRole
(
ctx
api
.
Context
,
clusterRole
*
rbac
.
ClusterRole
)
error
GetClusterRole
(
ctx
api
.
Context
,
name
string
)
(
*
rbac
.
ClusterRole
,
error
)
DeleteClusterRole
(
ctx
api
.
Context
,
name
string
)
error
WatchClusterRoles
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
watch
.
Interface
,
error
)
}
// storage puts strong typing around storage calls
type
storage
struct
{
rest
.
StandardStorage
}
// NewRegistry returns a new Registry interface for the given Storage. Any mismatched
// types will panic.
func
NewRegistry
(
s
rest
.
StandardStorage
)
Registry
{
return
&
storage
{
s
}
}
func
(
s
*
storage
)
ListClusterRoles
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
*
rbac
.
ClusterRoleList
,
error
)
{
obj
,
err
:=
s
.
List
(
ctx
,
options
)
if
err
!=
nil
{
return
nil
,
err
}
return
obj
.
(
*
rbac
.
ClusterRoleList
),
nil
}
func
(
s
*
storage
)
CreateClusterRole
(
ctx
api
.
Context
,
clusterRole
*
rbac
.
ClusterRole
)
error
{
_
,
err
:=
s
.
Create
(
ctx
,
clusterRole
)
return
err
}
func
(
s
*
storage
)
UpdateClusterRole
(
ctx
api
.
Context
,
clusterRole
*
rbac
.
ClusterRole
)
error
{
_
,
_
,
err
:=
s
.
Update
(
ctx
,
clusterRole
.
Name
,
rest
.
DefaultUpdatedObjectInfo
(
clusterRole
,
api
.
Scheme
))
return
err
}
func
(
s
*
storage
)
WatchClusterRoles
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
s
.
Watch
(
ctx
,
options
)
}
func
(
s
*
storage
)
GetClusterRole
(
ctx
api
.
Context
,
name
string
)
(
*
rbac
.
ClusterRole
,
error
)
{
obj
,
err
:=
s
.
Get
(
ctx
,
name
)
if
err
!=
nil
{
return
nil
,
err
}
return
obj
.
(
*
rbac
.
ClusterRole
),
nil
}
func
(
s
*
storage
)
DeleteClusterRole
(
ctx
api
.
Context
,
name
string
)
error
{
_
,
err
:=
s
.
Delete
(
ctx
,
name
,
nil
)
return
err
}
pkg/registry/clusterrole/strategy.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
clusterrole
import
(
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/validation/field"
)
// strategy implements behavior for ClusterRoles
type
strategy
struct
{
runtime
.
ObjectTyper
api
.
NameGenerator
}
// strategy is the default logic that applies when creating and updating
// ClusterRole objects.
var
Strategy
=
strategy
{
api
.
Scheme
,
api
.
SimpleNameGenerator
}
// Strategy should implement rest.RESTCreateStrategy
var
_
rest
.
RESTCreateStrategy
=
Strategy
// Strategy should implement rest.RESTUpdateStrategy
var
_
rest
.
RESTUpdateStrategy
=
Strategy
// NamespaceScoped is true for ClusterRoles.
func
(
strategy
)
NamespaceScoped
()
bool
{
return
false
}
// AllowCreateOnUpdate is true for ClusterRoles.
func
(
strategy
)
AllowCreateOnUpdate
()
bool
{
return
true
}
// PrepareForCreate clears fields that are not allowed to be set by end users
// on creation.
func
(
strategy
)
PrepareForCreate
(
obj
runtime
.
Object
)
{
_
=
obj
.
(
*
rbac
.
ClusterRole
)
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func
(
strategy
)
PrepareForUpdate
(
obj
,
old
runtime
.
Object
)
{
newClusterRole
:=
obj
.
(
*
rbac
.
ClusterRole
)
oldClusterRole
:=
old
.
(
*
rbac
.
ClusterRole
)
_
,
_
=
newClusterRole
,
oldClusterRole
}
// Validate validates a new ClusterRole. Validation must check for a correct signature.
func
(
strategy
)
Validate
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
field
.
ErrorList
{
clusterRole
:=
obj
.
(
*
rbac
.
ClusterRole
)
return
validation
.
ValidateClusterRole
(
clusterRole
)
}
// Canonicalize normalizes the object after validation.
func
(
strategy
)
Canonicalize
(
obj
runtime
.
Object
)
{
_
=
obj
.
(
*
rbac
.
ClusterRole
)
}
// ValidateUpdate is the default update validation for an end user.
func
(
strategy
)
ValidateUpdate
(
ctx
api
.
Context
,
obj
,
old
runtime
.
Object
)
field
.
ErrorList
{
newObj
:=
obj
.
(
*
rbac
.
ClusterRole
)
errorList
:=
validation
.
ValidateClusterRole
(
newObj
)
return
append
(
errorList
,
validation
.
ValidateClusterRoleUpdate
(
newObj
,
old
.
(
*
rbac
.
ClusterRole
))
...
)
}
// If AllowUnconditionalUpdate() is true and the object specified by
// the user does not have a resource version, then generic Update()
// populates it with the latest version. Else, it checks that the
// version specified by the user matches the version of latest etcd
// object.
func
(
strategy
)
AllowUnconditionalUpdate
()
bool
{
return
true
}
func
(
s
strategy
)
Export
(
obj
runtime
.
Object
,
exact
bool
)
error
{
return
nil
}
// Matcher returns a generic matcher for a given label and field selector.
func
Matcher
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
generic
.
MatcherFunc
(
func
(
obj
runtime
.
Object
)
(
bool
,
error
)
{
sa
,
ok
:=
obj
.
(
*
rbac
.
ClusterRole
)
if
!
ok
{
return
false
,
fmt
.
Errorf
(
"not a ClusterRole"
)
}
fields
:=
SelectableFields
(
sa
)
return
label
.
Matches
(
labels
.
Set
(
sa
.
Labels
))
&&
field
.
Matches
(
fields
),
nil
})
}
// SelectableFields returns a label set that can be used for filter selection
func
SelectableFields
(
obj
*
rbac
.
ClusterRole
)
labels
.
Set
{
return
labels
.
Set
{}
}
pkg/registry/clusterrolebinding/doc.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 certificates provides Registry interface and its RESTStorage
// implementation for storing ClusterRoleBinding objects.
package
clusterrolebinding
pkg/registry/clusterrolebinding/etcd/etcd.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
etcd
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/clusterrolebinding"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/runtime"
)
// REST implements a RESTStorage for ClusterRoleBinding against etcd
type
REST
struct
{
*
registry
.
Store
}
// NewREST returns a RESTStorage object that will work against ClusterRoleBinding objects.
func
NewREST
(
opts
generic
.
RESTOptions
)
*
REST
{
prefix
:=
"/clusterrolebindings"
newListFunc
:=
func
()
runtime
.
Object
{
return
&
rbac
.
ClusterRoleBindingList
{}
}
storageInterface
:=
opts
.
Decorator
(
opts
.
Storage
,
cachesize
.
GetWatchCacheSizeByResource
(
cachesize
.
ClusterRoleBindings
),
&
rbac
.
ClusterRoleBinding
{},
prefix
,
clusterrolebinding
.
Strategy
,
newListFunc
,
)
store
:=
&
registry
.
Store
{
NewFunc
:
func
()
runtime
.
Object
{
return
&
rbac
.
ClusterRoleBinding
{}
},
NewListFunc
:
newListFunc
,
KeyRootFunc
:
func
(
ctx
api
.
Context
)
string
{
return
registry
.
NamespaceKeyRootFunc
(
ctx
,
prefix
)
},
KeyFunc
:
func
(
ctx
api
.
Context
,
id
string
)
(
string
,
error
)
{
return
registry
.
NoNamespaceKeyFunc
(
ctx
,
prefix
,
id
)
},
ObjectNameFunc
:
func
(
obj
runtime
.
Object
)
(
string
,
error
)
{
return
obj
.
(
*
rbac
.
ClusterRoleBinding
)
.
Name
,
nil
},
PredicateFunc
:
func
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
clusterrolebinding
.
Matcher
(
label
,
field
)
},
QualifiedResource
:
rbac
.
Resource
(
"clusterrolebindings"
),
DeleteCollectionWorkers
:
opts
.
DeleteCollectionWorkers
,
CreateStrategy
:
clusterrolebinding
.
Strategy
,
UpdateStrategy
:
clusterrolebinding
.
Strategy
,
DeleteStrategy
:
clusterrolebinding
.
Strategy
,
Storage
:
storageInterface
,
}
return
&
REST
{
store
}
}
pkg/registry/clusterrolebinding/policybased/storage.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 policybased implements a standard storage for ClusterRoleBinding that prevents privilege escalation.
package
policybased
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
"k8s.io/kubernetes/pkg/runtime"
)
var
groupResource
=
rbac
.
Resource
(
"clusterrolebindings"
)
type
Storage
struct
{
rest
.
StandardStorage
ruleResolver
validation
.
AuthorizationRuleResolver
// user which skips privilege escalation checks
superUser
string
}
func
NewStorage
(
s
rest
.
StandardStorage
,
ruleResolver
validation
.
AuthorizationRuleResolver
,
superUser
string
)
*
Storage
{
return
&
Storage
{
s
,
ruleResolver
,
superUser
}
}
func
(
s
*
Storage
)
Create
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
if
user
,
ok
:=
api
.
UserFrom
(
ctx
);
ok
{
if
s
.
superUser
!=
""
&&
user
.
GetName
()
==
s
.
superUser
{
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
)
}
}
clusterRoleBinding
:=
obj
.
(
*
rbac
.
ClusterRoleBinding
)
rules
,
err
:=
s
.
ruleResolver
.
GetRoleReferenceRules
(
ctx
,
clusterRoleBinding
.
RoleRef
,
clusterRoleBinding
.
Namespace
)
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
validation
.
ConfirmNoEscalation
(
ctx
,
s
.
ruleResolver
,
rules
);
err
!=
nil
{
return
nil
,
errors
.
NewForbidden
(
groupResource
,
clusterRoleBinding
.
Name
,
err
)
}
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
)
}
func
(
s
*
Storage
)
Update
(
ctx
api
.
Context
,
name
string
,
obj
rest
.
UpdatedObjectInfo
)
(
runtime
.
Object
,
bool
,
error
)
{
if
user
,
ok
:=
api
.
UserFrom
(
ctx
);
ok
{
if
s
.
superUser
!=
""
&&
user
.
GetName
()
==
s
.
superUser
{
return
s
.
StandardStorage
.
Update
(
ctx
,
name
,
obj
)
}
}
nonEscalatingInfo
:=
wrapUpdatedObjectInfo
(
obj
,
func
(
ctx
api
.
Context
,
obj
runtime
.
Object
,
oldObj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
clusterRoleBinding
:=
obj
.
(
*
rbac
.
ClusterRoleBinding
)
rules
,
err
:=
s
.
ruleResolver
.
GetRoleReferenceRules
(
ctx
,
clusterRoleBinding
.
RoleRef
,
clusterRoleBinding
.
Namespace
)
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
validation
.
ConfirmNoEscalation
(
ctx
,
s
.
ruleResolver
,
rules
);
err
!=
nil
{
return
nil
,
errors
.
NewForbidden
(
groupResource
,
clusterRoleBinding
.
Name
,
err
)
}
return
obj
,
nil
})
return
s
.
StandardStorage
.
Update
(
ctx
,
name
,
nonEscalatingInfo
)
}
// TODO(ericchiang): This logic is copied from #26240. Replace with once that PR is merged into master.
type
wrappedUpdatedObjectInfo
struct
{
objInfo
rest
.
UpdatedObjectInfo
transformFunc
rest
.
TransformFunc
}
func
wrapUpdatedObjectInfo
(
objInfo
rest
.
UpdatedObjectInfo
,
transformFunc
rest
.
TransformFunc
)
rest
.
UpdatedObjectInfo
{
return
&
wrappedUpdatedObjectInfo
{
objInfo
,
transformFunc
}
}
func
(
i
*
wrappedUpdatedObjectInfo
)
Preconditions
()
*
api
.
Preconditions
{
return
i
.
objInfo
.
Preconditions
()
}
func
(
i
*
wrappedUpdatedObjectInfo
)
UpdatedObject
(
ctx
api
.
Context
,
oldObj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
obj
,
err
:=
i
.
objInfo
.
UpdatedObject
(
ctx
,
oldObj
)
if
err
!=
nil
{
return
obj
,
err
}
return
i
.
transformFunc
(
ctx
,
obj
,
oldObj
)
}
pkg/registry/clusterrolebinding/registry.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
clusterrolebinding
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/watch"
)
// Registry is an interface for things that know how to store ClusterRoleBindings.
type
Registry
interface
{
ListClusterRoleBindings
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
*
rbac
.
ClusterRoleBindingList
,
error
)
CreateClusterRoleBinding
(
ctx
api
.
Context
,
clusterRoleBinding
*
rbac
.
ClusterRoleBinding
)
error
UpdateClusterRoleBinding
(
ctx
api
.
Context
,
clusterRoleBinding
*
rbac
.
ClusterRoleBinding
)
error
GetClusterRoleBinding
(
ctx
api
.
Context
,
name
string
)
(
*
rbac
.
ClusterRoleBinding
,
error
)
DeleteClusterRoleBinding
(
ctx
api
.
Context
,
name
string
)
error
WatchClusterRoleBindings
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
watch
.
Interface
,
error
)
}
// storage puts strong typing around storage calls
type
storage
struct
{
rest
.
StandardStorage
}
// NewRegistry returns a new Registry interface for the given Storage. Any mismatched
// types will panic.
func
NewRegistry
(
s
rest
.
StandardStorage
)
Registry
{
return
&
storage
{
s
}
}
func
(
s
*
storage
)
ListClusterRoleBindings
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
*
rbac
.
ClusterRoleBindingList
,
error
)
{
obj
,
err
:=
s
.
List
(
ctx
,
options
)
if
err
!=
nil
{
return
nil
,
err
}
return
obj
.
(
*
rbac
.
ClusterRoleBindingList
),
nil
}
func
(
s
*
storage
)
CreateClusterRoleBinding
(
ctx
api
.
Context
,
clusterRoleBinding
*
rbac
.
ClusterRoleBinding
)
error
{
_
,
err
:=
s
.
Create
(
ctx
,
clusterRoleBinding
)
return
err
}
func
(
s
*
storage
)
UpdateClusterRoleBinding
(
ctx
api
.
Context
,
clusterRoleBinding
*
rbac
.
ClusterRoleBinding
)
error
{
_
,
_
,
err
:=
s
.
Update
(
ctx
,
clusterRoleBinding
.
Name
,
rest
.
DefaultUpdatedObjectInfo
(
clusterRoleBinding
,
api
.
Scheme
))
return
err
}
func
(
s
*
storage
)
WatchClusterRoleBindings
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
s
.
Watch
(
ctx
,
options
)
}
func
(
s
*
storage
)
GetClusterRoleBinding
(
ctx
api
.
Context
,
name
string
)
(
*
rbac
.
ClusterRoleBinding
,
error
)
{
obj
,
err
:=
s
.
Get
(
ctx
,
name
)
if
err
!=
nil
{
return
nil
,
err
}
return
obj
.
(
*
rbac
.
ClusterRoleBinding
),
nil
}
func
(
s
*
storage
)
DeleteClusterRoleBinding
(
ctx
api
.
Context
,
name
string
)
error
{
_
,
err
:=
s
.
Delete
(
ctx
,
name
,
nil
)
return
err
}
pkg/registry/clusterrolebinding/strategy.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
clusterrolebinding
import
(
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/validation/field"
)
// strategy implements behavior for ClusterRoleBindings
type
strategy
struct
{
runtime
.
ObjectTyper
api
.
NameGenerator
}
// strategy is the default logic that applies when creating and updating
// ClusterRoleBinding objects.
var
Strategy
=
strategy
{
api
.
Scheme
,
api
.
SimpleNameGenerator
}
// Strategy should implement rest.RESTCreateStrategy
var
_
rest
.
RESTCreateStrategy
=
Strategy
// Strategy should implement rest.RESTUpdateStrategy
var
_
rest
.
RESTUpdateStrategy
=
Strategy
// NamespaceScoped is true for ClusterRoleBindings.
func
(
strategy
)
NamespaceScoped
()
bool
{
return
false
}
// AllowCreateOnUpdate is true for ClusterRoleBindings.
func
(
strategy
)
AllowCreateOnUpdate
()
bool
{
return
true
}
// PrepareForCreate clears fields that are not allowed to be set by end users
// on creation.
func
(
strategy
)
PrepareForCreate
(
obj
runtime
.
Object
)
{
_
=
obj
.
(
*
rbac
.
ClusterRoleBinding
)
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func
(
strategy
)
PrepareForUpdate
(
obj
,
old
runtime
.
Object
)
{
newClusterRoleBinding
:=
obj
.
(
*
rbac
.
ClusterRoleBinding
)
oldClusterRoleBinding
:=
old
.
(
*
rbac
.
ClusterRoleBinding
)
_
,
_
=
newClusterRoleBinding
,
oldClusterRoleBinding
}
// Validate validates a new ClusterRoleBinding. Validation must check for a correct signature.
func
(
strategy
)
Validate
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
field
.
ErrorList
{
clusterRoleBinding
:=
obj
.
(
*
rbac
.
ClusterRoleBinding
)
return
validation
.
ValidateClusterRoleBinding
(
clusterRoleBinding
)
}
// Canonicalize normalizes the object after validation.
func
(
strategy
)
Canonicalize
(
obj
runtime
.
Object
)
{
_
=
obj
.
(
*
rbac
.
ClusterRoleBinding
)
}
// ValidateUpdate is the default update validation for an end user.
func
(
strategy
)
ValidateUpdate
(
ctx
api
.
Context
,
obj
,
old
runtime
.
Object
)
field
.
ErrorList
{
newObj
:=
obj
.
(
*
rbac
.
ClusterRoleBinding
)
errorList
:=
validation
.
ValidateClusterRoleBinding
(
newObj
)
return
append
(
errorList
,
validation
.
ValidateClusterRoleBindingUpdate
(
newObj
,
old
.
(
*
rbac
.
ClusterRoleBinding
))
...
)
}
// If AllowUnconditionalUpdate() is true and the object specified by
// the user does not have a resource version, then generic Update()
// populates it with the latest version. Else, it checks that the
// version specified by the user matches the version of latest etcd
// object.
func
(
strategy
)
AllowUnconditionalUpdate
()
bool
{
return
true
}
func
(
s
strategy
)
Export
(
obj
runtime
.
Object
,
exact
bool
)
error
{
return
nil
}
// Matcher returns a generic matcher for a given label and field selector.
func
Matcher
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
generic
.
MatcherFunc
(
func
(
obj
runtime
.
Object
)
(
bool
,
error
)
{
sa
,
ok
:=
obj
.
(
*
rbac
.
ClusterRoleBinding
)
if
!
ok
{
return
false
,
fmt
.
Errorf
(
"not a ClusterRoleBinding"
)
}
fields
:=
SelectableFields
(
sa
)
return
label
.
Matches
(
labels
.
Set
(
sa
.
Labels
))
&&
field
.
Matches
(
fields
),
nil
})
}
// SelectableFields returns a label set that can be used for filter selection
func
SelectableFields
(
obj
*
rbac
.
ClusterRoleBinding
)
labels
.
Set
{
return
labels
.
Set
{}
}
pkg/registry/role/doc.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 certificates provides Registry interface and its RESTStorage
// implementation for storing Role objects.
package
role
pkg/registry/role/etcd/etcd.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
etcd
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/registry/role"
"k8s.io/kubernetes/pkg/runtime"
)
// REST implements a RESTStorage for Role against etcd
type
REST
struct
{
*
registry
.
Store
}
// NewREST returns a RESTStorage object that will work against Role objects.
func
NewREST
(
opts
generic
.
RESTOptions
)
*
REST
{
prefix
:=
"/roles"
newListFunc
:=
func
()
runtime
.
Object
{
return
&
rbac
.
RoleList
{}
}
storageInterface
:=
opts
.
Decorator
(
opts
.
Storage
,
cachesize
.
GetWatchCacheSizeByResource
(
cachesize
.
Roles
),
&
rbac
.
Role
{},
prefix
,
role
.
Strategy
,
newListFunc
,
)
store
:=
&
registry
.
Store
{
NewFunc
:
func
()
runtime
.
Object
{
return
&
rbac
.
Role
{}
},
NewListFunc
:
newListFunc
,
KeyRootFunc
:
func
(
ctx
api
.
Context
)
string
{
return
registry
.
NamespaceKeyRootFunc
(
ctx
,
prefix
)
},
KeyFunc
:
func
(
ctx
api
.
Context
,
id
string
)
(
string
,
error
)
{
return
registry
.
NamespaceKeyFunc
(
ctx
,
prefix
,
id
)
},
ObjectNameFunc
:
func
(
obj
runtime
.
Object
)
(
string
,
error
)
{
return
obj
.
(
*
rbac
.
Role
)
.
Name
,
nil
},
PredicateFunc
:
func
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
role
.
Matcher
(
label
,
field
)
},
QualifiedResource
:
rbac
.
Resource
(
"roles"
),
DeleteCollectionWorkers
:
opts
.
DeleteCollectionWorkers
,
CreateStrategy
:
role
.
Strategy
,
UpdateStrategy
:
role
.
Strategy
,
DeleteStrategy
:
role
.
Strategy
,
Storage
:
storageInterface
,
}
return
&
REST
{
store
}
}
pkg/registry/role/policybased/storage.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 policybased implements a standard storage for Role that prevents privilege escalation.
package
policybased
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
"k8s.io/kubernetes/pkg/runtime"
)
var
groupResource
=
rbac
.
Resource
(
"roles"
)
type
Storage
struct
{
rest
.
StandardStorage
ruleResolver
validation
.
AuthorizationRuleResolver
// user which skips privilege escalation checks
superUser
string
}
func
NewStorage
(
s
rest
.
StandardStorage
,
ruleResolver
validation
.
AuthorizationRuleResolver
,
superUser
string
)
*
Storage
{
return
&
Storage
{
s
,
ruleResolver
,
superUser
}
}
func
(
s
*
Storage
)
Create
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
if
user
,
ok
:=
api
.
UserFrom
(
ctx
);
ok
{
if
s
.
superUser
!=
""
&&
user
.
GetName
()
==
s
.
superUser
{
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
)
}
}
role
:=
obj
.
(
*
rbac
.
Role
)
rules
:=
role
.
Rules
if
err
:=
validation
.
ConfirmNoEscalation
(
ctx
,
s
.
ruleResolver
,
rules
);
err
!=
nil
{
return
nil
,
errors
.
NewForbidden
(
groupResource
,
role
.
Name
,
err
)
}
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
)
}
func
(
s
*
Storage
)
Update
(
ctx
api
.
Context
,
name
string
,
obj
rest
.
UpdatedObjectInfo
)
(
runtime
.
Object
,
bool
,
error
)
{
if
user
,
ok
:=
api
.
UserFrom
(
ctx
);
ok
{
if
s
.
superUser
!=
""
&&
user
.
GetName
()
==
s
.
superUser
{
return
s
.
StandardStorage
.
Update
(
ctx
,
name
,
obj
)
}
}
nonEscalatingInfo
:=
wrapUpdatedObjectInfo
(
obj
,
func
(
ctx
api
.
Context
,
obj
runtime
.
Object
,
oldObj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
role
:=
obj
.
(
*
rbac
.
Role
)
rules
:=
role
.
Rules
if
err
:=
validation
.
ConfirmNoEscalation
(
ctx
,
s
.
ruleResolver
,
rules
);
err
!=
nil
{
return
nil
,
errors
.
NewForbidden
(
groupResource
,
role
.
Name
,
err
)
}
return
obj
,
nil
})
return
s
.
StandardStorage
.
Update
(
ctx
,
name
,
nonEscalatingInfo
)
}
// TODO(ericchiang): This logic is copied from #26240. Replace with once that PR is merged into master.
type
wrappedUpdatedObjectInfo
struct
{
objInfo
rest
.
UpdatedObjectInfo
transformFunc
rest
.
TransformFunc
}
func
wrapUpdatedObjectInfo
(
objInfo
rest
.
UpdatedObjectInfo
,
transformFunc
rest
.
TransformFunc
)
rest
.
UpdatedObjectInfo
{
return
&
wrappedUpdatedObjectInfo
{
objInfo
,
transformFunc
}
}
func
(
i
*
wrappedUpdatedObjectInfo
)
Preconditions
()
*
api
.
Preconditions
{
return
i
.
objInfo
.
Preconditions
()
}
func
(
i
*
wrappedUpdatedObjectInfo
)
UpdatedObject
(
ctx
api
.
Context
,
oldObj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
obj
,
err
:=
i
.
objInfo
.
UpdatedObject
(
ctx
,
oldObj
)
if
err
!=
nil
{
return
obj
,
err
}
return
i
.
transformFunc
(
ctx
,
obj
,
oldObj
)
}
pkg/registry/role/registry.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
role
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/watch"
)
// Registry is an interface for things that know how to store Roles.
type
Registry
interface
{
ListRoles
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
*
rbac
.
RoleList
,
error
)
CreateRole
(
ctx
api
.
Context
,
role
*
rbac
.
Role
)
error
UpdateRole
(
ctx
api
.
Context
,
role
*
rbac
.
Role
)
error
GetRole
(
ctx
api
.
Context
,
name
string
)
(
*
rbac
.
Role
,
error
)
DeleteRole
(
ctx
api
.
Context
,
name
string
)
error
WatchRoles
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
watch
.
Interface
,
error
)
}
// storage puts strong typing around storage calls
type
storage
struct
{
rest
.
StandardStorage
}
// NewRegistry returns a new Registry interface for the given Storage. Any mismatched
// types will panic.
func
NewRegistry
(
s
rest
.
StandardStorage
)
Registry
{
return
&
storage
{
s
}
}
func
(
s
*
storage
)
ListRoles
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
*
rbac
.
RoleList
,
error
)
{
obj
,
err
:=
s
.
List
(
ctx
,
options
)
if
err
!=
nil
{
return
nil
,
err
}
return
obj
.
(
*
rbac
.
RoleList
),
nil
}
func
(
s
*
storage
)
CreateRole
(
ctx
api
.
Context
,
role
*
rbac
.
Role
)
error
{
_
,
err
:=
s
.
Create
(
ctx
,
role
)
return
err
}
func
(
s
*
storage
)
UpdateRole
(
ctx
api
.
Context
,
role
*
rbac
.
Role
)
error
{
_
,
_
,
err
:=
s
.
Update
(
ctx
,
role
.
Name
,
rest
.
DefaultUpdatedObjectInfo
(
role
,
api
.
Scheme
))
return
err
}
func
(
s
*
storage
)
WatchRoles
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
s
.
Watch
(
ctx
,
options
)
}
func
(
s
*
storage
)
GetRole
(
ctx
api
.
Context
,
name
string
)
(
*
rbac
.
Role
,
error
)
{
obj
,
err
:=
s
.
Get
(
ctx
,
name
)
if
err
!=
nil
{
return
nil
,
err
}
return
obj
.
(
*
rbac
.
Role
),
nil
}
func
(
s
*
storage
)
DeleteRole
(
ctx
api
.
Context
,
name
string
)
error
{
_
,
err
:=
s
.
Delete
(
ctx
,
name
,
nil
)
return
err
}
pkg/registry/role/strategy.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
role
import
(
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/validation/field"
)
// strategy implements behavior for Roles
type
strategy
struct
{
runtime
.
ObjectTyper
api
.
NameGenerator
}
// strategy is the default logic that applies when creating and updating
// Role objects.
var
Strategy
=
strategy
{
api
.
Scheme
,
api
.
SimpleNameGenerator
}
// Strategy should implement rest.RESTCreateStrategy
var
_
rest
.
RESTCreateStrategy
=
Strategy
// Strategy should implement rest.RESTUpdateStrategy
var
_
rest
.
RESTUpdateStrategy
=
Strategy
// NamespaceScoped is true for Roles.
func
(
strategy
)
NamespaceScoped
()
bool
{
return
true
}
// AllowCreateOnUpdate is true for Roles.
func
(
strategy
)
AllowCreateOnUpdate
()
bool
{
return
true
}
// PrepareForCreate clears fields that are not allowed to be set by end users
// on creation.
func
(
strategy
)
PrepareForCreate
(
obj
runtime
.
Object
)
{
_
=
obj
.
(
*
rbac
.
Role
)
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func
(
strategy
)
PrepareForUpdate
(
obj
,
old
runtime
.
Object
)
{
newRole
:=
obj
.
(
*
rbac
.
Role
)
oldRole
:=
old
.
(
*
rbac
.
Role
)
_
,
_
=
newRole
,
oldRole
}
// Validate validates a new Role. Validation must check for a correct signature.
func
(
strategy
)
Validate
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
field
.
ErrorList
{
role
:=
obj
.
(
*
rbac
.
Role
)
return
validation
.
ValidateRole
(
role
)
}
// Canonicalize normalizes the object after validation.
func
(
strategy
)
Canonicalize
(
obj
runtime
.
Object
)
{
_
=
obj
.
(
*
rbac
.
Role
)
}
// ValidateUpdate is the default update validation for an end user.
func
(
strategy
)
ValidateUpdate
(
ctx
api
.
Context
,
obj
,
old
runtime
.
Object
)
field
.
ErrorList
{
newObj
:=
obj
.
(
*
rbac
.
Role
)
errorList
:=
validation
.
ValidateRole
(
newObj
)
return
append
(
errorList
,
validation
.
ValidateRoleUpdate
(
newObj
,
old
.
(
*
rbac
.
Role
))
...
)
}
// If AllowUnconditionalUpdate() is true and the object specified by
// the user does not have a resource version, then generic Update()
// populates it with the latest version. Else, it checks that the
// version specified by the user matches the version of latest etcd
// object.
func
(
strategy
)
AllowUnconditionalUpdate
()
bool
{
return
true
}
func
(
s
strategy
)
Export
(
obj
runtime
.
Object
,
exact
bool
)
error
{
return
nil
}
// Matcher returns a generic matcher for a given label and field selector.
func
Matcher
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
generic
.
MatcherFunc
(
func
(
obj
runtime
.
Object
)
(
bool
,
error
)
{
sa
,
ok
:=
obj
.
(
*
rbac
.
Role
)
if
!
ok
{
return
false
,
fmt
.
Errorf
(
"not a Role"
)
}
fields
:=
SelectableFields
(
sa
)
return
label
.
Matches
(
labels
.
Set
(
sa
.
Labels
))
&&
field
.
Matches
(
fields
),
nil
})
}
// SelectableFields returns a label set that can be used for filter selection
func
SelectableFields
(
obj
*
rbac
.
Role
)
labels
.
Set
{
return
labels
.
Set
{}
}
pkg/registry/rolebinding/doc.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 certificates provides Registry interface and its RESTStorage
// implementation for storing RoleBinding objects.
package
rolebinding
pkg/registry/rolebinding/etcd/etcd.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
etcd
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/registry/generic/registry"
"k8s.io/kubernetes/pkg/registry/rolebinding"
"k8s.io/kubernetes/pkg/runtime"
)
// REST implements a RESTStorage for RoleBinding against etcd
type
REST
struct
{
*
registry
.
Store
}
// NewREST returns a RESTStorage object that will work against RoleBinding objects.
func
NewREST
(
opts
generic
.
RESTOptions
)
*
REST
{
prefix
:=
"/rolebindings"
newListFunc
:=
func
()
runtime
.
Object
{
return
&
rbac
.
RoleBindingList
{}
}
storageInterface
:=
opts
.
Decorator
(
opts
.
Storage
,
cachesize
.
GetWatchCacheSizeByResource
(
cachesize
.
RoleBindings
),
&
rbac
.
RoleBinding
{},
prefix
,
rolebinding
.
Strategy
,
newListFunc
,
)
store
:=
&
registry
.
Store
{
NewFunc
:
func
()
runtime
.
Object
{
return
&
rbac
.
RoleBinding
{}
},
NewListFunc
:
newListFunc
,
KeyRootFunc
:
func
(
ctx
api
.
Context
)
string
{
return
registry
.
NamespaceKeyRootFunc
(
ctx
,
prefix
)
},
KeyFunc
:
func
(
ctx
api
.
Context
,
id
string
)
(
string
,
error
)
{
return
registry
.
NamespaceKeyFunc
(
ctx
,
prefix
,
id
)
},
ObjectNameFunc
:
func
(
obj
runtime
.
Object
)
(
string
,
error
)
{
return
obj
.
(
*
rbac
.
RoleBinding
)
.
Name
,
nil
},
PredicateFunc
:
func
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
rolebinding
.
Matcher
(
label
,
field
)
},
QualifiedResource
:
rbac
.
Resource
(
"rolebindings"
),
DeleteCollectionWorkers
:
opts
.
DeleteCollectionWorkers
,
CreateStrategy
:
rolebinding
.
Strategy
,
UpdateStrategy
:
rolebinding
.
Strategy
,
DeleteStrategy
:
rolebinding
.
Strategy
,
Storage
:
storageInterface
,
}
return
&
REST
{
store
}
}
pkg/registry/rolebinding/policybased/storage.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 policybased implements a standard storage for RoleBinding that prevents privilege escalation.
package
policybased
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
"k8s.io/kubernetes/pkg/runtime"
)
var
groupResource
=
rbac
.
Resource
(
"rolebindings"
)
type
Storage
struct
{
rest
.
StandardStorage
ruleResolver
validation
.
AuthorizationRuleResolver
// user which skips privilege escalation checks
superUser
string
}
func
NewStorage
(
s
rest
.
StandardStorage
,
ruleResolver
validation
.
AuthorizationRuleResolver
,
superUser
string
)
*
Storage
{
return
&
Storage
{
s
,
ruleResolver
,
superUser
}
}
func
(
s
*
Storage
)
Create
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
if
user
,
ok
:=
api
.
UserFrom
(
ctx
);
ok
{
if
s
.
superUser
!=
""
&&
user
.
GetName
()
==
s
.
superUser
{
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
)
}
}
roleBinding
:=
obj
.
(
*
rbac
.
RoleBinding
)
rules
,
err
:=
s
.
ruleResolver
.
GetRoleReferenceRules
(
ctx
,
roleBinding
.
RoleRef
,
roleBinding
.
Namespace
)
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
validation
.
ConfirmNoEscalation
(
ctx
,
s
.
ruleResolver
,
rules
);
err
!=
nil
{
return
nil
,
errors
.
NewForbidden
(
groupResource
,
roleBinding
.
Name
,
err
)
}
return
s
.
StandardStorage
.
Create
(
ctx
,
obj
)
}
func
(
s
*
Storage
)
Update
(
ctx
api
.
Context
,
name
string
,
obj
rest
.
UpdatedObjectInfo
)
(
runtime
.
Object
,
bool
,
error
)
{
if
user
,
ok
:=
api
.
UserFrom
(
ctx
);
ok
{
if
s
.
superUser
!=
""
&&
user
.
GetName
()
==
s
.
superUser
{
return
s
.
StandardStorage
.
Update
(
ctx
,
name
,
obj
)
}
}
nonEscalatingInfo
:=
wrapUpdatedObjectInfo
(
obj
,
func
(
ctx
api
.
Context
,
obj
runtime
.
Object
,
oldObj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
roleBinding
:=
obj
.
(
*
rbac
.
RoleBinding
)
rules
,
err
:=
s
.
ruleResolver
.
GetRoleReferenceRules
(
ctx
,
roleBinding
.
RoleRef
,
roleBinding
.
Namespace
)
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
validation
.
ConfirmNoEscalation
(
ctx
,
s
.
ruleResolver
,
rules
);
err
!=
nil
{
return
nil
,
errors
.
NewForbidden
(
groupResource
,
roleBinding
.
Name
,
err
)
}
return
obj
,
nil
})
return
s
.
StandardStorage
.
Update
(
ctx
,
name
,
nonEscalatingInfo
)
}
// TODO(ericchiang): This logic is copied from #26240. Replace with once that PR is merged into master.
type
wrappedUpdatedObjectInfo
struct
{
objInfo
rest
.
UpdatedObjectInfo
transformFunc
rest
.
TransformFunc
}
func
wrapUpdatedObjectInfo
(
objInfo
rest
.
UpdatedObjectInfo
,
transformFunc
rest
.
TransformFunc
)
rest
.
UpdatedObjectInfo
{
return
&
wrappedUpdatedObjectInfo
{
objInfo
,
transformFunc
}
}
func
(
i
*
wrappedUpdatedObjectInfo
)
Preconditions
()
*
api
.
Preconditions
{
return
i
.
objInfo
.
Preconditions
()
}
func
(
i
*
wrappedUpdatedObjectInfo
)
UpdatedObject
(
ctx
api
.
Context
,
oldObj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
obj
,
err
:=
i
.
objInfo
.
UpdatedObject
(
ctx
,
oldObj
)
if
err
!=
nil
{
return
obj
,
err
}
return
i
.
transformFunc
(
ctx
,
obj
,
oldObj
)
}
pkg/registry/rolebinding/registry.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
rolebinding
import
(
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/watch"
)
// Registry is an interface for things that know how to store RoleBindings.
type
Registry
interface
{
ListRoleBindings
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
*
rbac
.
RoleBindingList
,
error
)
CreateRoleBinding
(
ctx
api
.
Context
,
roleBinding
*
rbac
.
RoleBinding
)
error
UpdateRoleBinding
(
ctx
api
.
Context
,
roleBinding
*
rbac
.
RoleBinding
)
error
GetRoleBinding
(
ctx
api
.
Context
,
name
string
)
(
*
rbac
.
RoleBinding
,
error
)
DeleteRoleBinding
(
ctx
api
.
Context
,
name
string
)
error
WatchRoleBindings
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
watch
.
Interface
,
error
)
}
// storage puts strong typing around storage calls
type
storage
struct
{
rest
.
StandardStorage
}
// NewRegistry returns a new Registry interface for the given Storage. Any mismatched
// types will panic.
func
NewRegistry
(
s
rest
.
StandardStorage
)
Registry
{
return
&
storage
{
s
}
}
func
(
s
*
storage
)
ListRoleBindings
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
*
rbac
.
RoleBindingList
,
error
)
{
obj
,
err
:=
s
.
List
(
ctx
,
options
)
if
err
!=
nil
{
return
nil
,
err
}
return
obj
.
(
*
rbac
.
RoleBindingList
),
nil
}
func
(
s
*
storage
)
CreateRoleBinding
(
ctx
api
.
Context
,
roleBinding
*
rbac
.
RoleBinding
)
error
{
// TODO(ericchiang): add additional validation
_
,
err
:=
s
.
Create
(
ctx
,
roleBinding
)
return
err
}
func
(
s
*
storage
)
UpdateRoleBinding
(
ctx
api
.
Context
,
roleBinding
*
rbac
.
RoleBinding
)
error
{
_
,
_
,
err
:=
s
.
Update
(
ctx
,
roleBinding
.
Name
,
rest
.
DefaultUpdatedObjectInfo
(
roleBinding
,
api
.
Scheme
))
return
err
}
func
(
s
*
storage
)
WatchRoleBindings
(
ctx
api
.
Context
,
options
*
api
.
ListOptions
)
(
watch
.
Interface
,
error
)
{
return
s
.
Watch
(
ctx
,
options
)
}
func
(
s
*
storage
)
GetRoleBinding
(
ctx
api
.
Context
,
name
string
)
(
*
rbac
.
RoleBinding
,
error
)
{
obj
,
err
:=
s
.
Get
(
ctx
,
name
)
if
err
!=
nil
{
return
nil
,
err
}
return
obj
.
(
*
rbac
.
RoleBinding
),
nil
}
func
(
s
*
storage
)
DeleteRoleBinding
(
ctx
api
.
Context
,
name
string
)
error
{
_
,
err
:=
s
.
Delete
(
ctx
,
name
,
nil
)
return
err
}
pkg/registry/rolebinding/strategy.go
0 → 100644
View file @
6f312f14
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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
rolebinding
import
(
"fmt"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/apis/rbac"
"k8s.io/kubernetes/pkg/apis/rbac/validation"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/validation/field"
)
// strategy implements behavior for RoleBindings
type
strategy
struct
{
runtime
.
ObjectTyper
api
.
NameGenerator
}
// strategy is the default logic that applies when creating and updating
// RoleBinding objects.
var
Strategy
=
strategy
{
api
.
Scheme
,
api
.
SimpleNameGenerator
}
// Strategy should implement rest.RESTCreateStrategy
var
_
rest
.
RESTCreateStrategy
=
Strategy
// Strategy should implement rest.RESTUpdateStrategy
var
_
rest
.
RESTUpdateStrategy
=
Strategy
// NamespaceScoped is true for RoleBindings.
func
(
strategy
)
NamespaceScoped
()
bool
{
return
true
}
// AllowCreateOnUpdate is true for RoleBindings.
func
(
strategy
)
AllowCreateOnUpdate
()
bool
{
return
true
}
// PrepareForCreate clears fields that are not allowed to be set by end users
// on creation.
func
(
strategy
)
PrepareForCreate
(
obj
runtime
.
Object
)
{
_
=
obj
.
(
*
rbac
.
RoleBinding
)
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func
(
strategy
)
PrepareForUpdate
(
obj
,
old
runtime
.
Object
)
{
newRoleBinding
:=
obj
.
(
*
rbac
.
RoleBinding
)
oldRoleBinding
:=
old
.
(
*
rbac
.
RoleBinding
)
_
,
_
=
newRoleBinding
,
oldRoleBinding
}
// Validate validates a new RoleBinding. Validation must check for a correct signature.
func
(
strategy
)
Validate
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
field
.
ErrorList
{
roleBinding
:=
obj
.
(
*
rbac
.
RoleBinding
)
return
validation
.
ValidateRoleBinding
(
roleBinding
)
}
// Canonicalize normalizes the object after validation.
func
(
strategy
)
Canonicalize
(
obj
runtime
.
Object
)
{
_
=
obj
.
(
*
rbac
.
RoleBinding
)
}
// ValidateUpdate is the default update validation for an end user.
func
(
strategy
)
ValidateUpdate
(
ctx
api
.
Context
,
obj
,
old
runtime
.
Object
)
field
.
ErrorList
{
newObj
:=
obj
.
(
*
rbac
.
RoleBinding
)
errorList
:=
validation
.
ValidateRoleBinding
(
newObj
)
return
append
(
errorList
,
validation
.
ValidateRoleBindingUpdate
(
newObj
,
old
.
(
*
rbac
.
RoleBinding
))
...
)
}
// If AllowUnconditionalUpdate() is true and the object specified by
// the user does not have a resource version, then generic Update()
// populates it with the latest version. Else, it checks that the
// version specified by the user matches the version of latest etcd
// object.
func
(
strategy
)
AllowUnconditionalUpdate
()
bool
{
return
true
}
func
(
s
strategy
)
Export
(
obj
runtime
.
Object
,
exact
bool
)
error
{
return
nil
}
// Matcher returns a generic matcher for a given label and field selector.
func
Matcher
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
generic
.
MatcherFunc
(
func
(
obj
runtime
.
Object
)
(
bool
,
error
)
{
sa
,
ok
:=
obj
.
(
*
rbac
.
RoleBinding
)
if
!
ok
{
return
false
,
fmt
.
Errorf
(
"not a RoleBinding"
)
}
fields
:=
SelectableFields
(
sa
)
return
label
.
Matches
(
labels
.
Set
(
sa
.
Labels
))
&&
field
.
Matches
(
fields
),
nil
})
}
// SelectableFields returns a label set that can be used for filter selection
func
SelectableFields
(
obj
*
rbac
.
RoleBinding
)
labels
.
Set
{
return
labels
.
Set
{}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment