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
02e16cb2
Commit
02e16cb2
authored
Oct 19, 2017
by
David Eads
Committed by
Dr. Stefan Schimanski
Nov 02, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add wiring for validating admission
parent
c3f31376
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
160 additions
and
29 deletions
+160
-29
interfaces.go
staging/src/k8s.io/apiserver/pkg/admission/interfaces.go
+10
-0
create.go
...ing/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go
+18
-12
delete.go
...ing/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go
+25
-6
update.go
...ing/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go
+12
-5
store.go
...c/k8s.io/apiserver/pkg/registry/generic/registry/store.go
+37
-2
create.go
staging/src/k8s.io/apiserver/pkg/registry/rest/create.go
+22
-0
rest.go
staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go
+14
-4
update.go
staging/src/k8s.io/apiserver/pkg/registry/rest/update.go
+22
-0
No files found.
staging/src/k8s.io/apiserver/pkg/admission/interfaces.go
View file @
02e16cb2
...
...
@@ -61,6 +61,16 @@ type Interface interface {
Handles
(
operation
Operation
)
bool
}
// ValidationInterface is an abstract, pluggable interface for Admission Control decisions.
type
ValidationInterface
interface
{
// Validate makes an admission decision based on the request attributes. It is NOT allowed to mutate
Validate
(
a
Attributes
)
(
err
error
)
// Handles returns true if this admission controller can handle the given operation
// where operation can be one of CREATE, UPDATE, DELETE, or CONNECT
Handles
(
operation
Operation
)
bool
}
// Operation is the type of resource operation being checked for admission control
type
Operation
string
...
...
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go
View file @
02e16cb2
...
...
@@ -34,7 +34,7 @@ import (
utiltrace
"k8s.io/apiserver/pkg/util/trace"
)
func
createHandler
(
r
rest
.
NamedCreater
,
scope
RequestScope
,
typer
runtime
.
ObjectTyper
,
admit
admission
.
Interface
,
includeName
bool
)
http
.
HandlerFunc
{
func
createHandler
(
r
rest
.
NamedCreater
,
scope
RequestScope
,
typer
runtime
.
ObjectTyper
,
mutatingAdmission
admission
.
Interface
,
validatingAdmission
admission
.
Validation
Interface
,
includeName
bool
)
http
.
HandlerFunc
{
return
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
// For performance tracking purposes.
trace
:=
utiltrace
.
New
(
"Create "
+
req
.
URL
.
Path
)
...
...
@@ -93,10 +93,10 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object
ae
:=
request
.
AuditEventFrom
(
ctx
)
audit
.
LogRequestObject
(
ae
,
obj
,
scope
.
Resource
,
scope
.
Subresource
,
scope
.
Serializer
)
if
admit
!=
nil
&&
admit
.
Handles
(
admission
.
Create
)
{
userInfo
,
_
:=
request
.
UserFrom
(
ctx
)
err
=
admit
.
Admit
(
admission
.
NewAttributesRecord
(
obj
,
nil
,
scope
.
Kind
,
namespace
,
name
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Create
,
userInfo
)
)
userInfo
,
_
:=
request
.
UserFrom
(
ctx
)
admissionAttributes
:=
admission
.
NewAttributesRecord
(
obj
,
nil
,
scope
.
Kind
,
namespace
,
name
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Create
,
userInfo
)
if
mutatingAdmission
!=
nil
&&
mutatingAdmission
.
Handles
(
admission
.
Create
)
{
err
=
mutatingAdmission
.
Admit
(
admissionAttributes
)
if
err
!=
nil
{
scope
.
err
(
err
,
w
,
req
)
return
...
...
@@ -108,7 +108,13 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object
trace
.
Step
(
"About to store object in database"
)
result
,
err
:=
finishRequest
(
timeout
,
func
()
(
runtime
.
Object
,
error
)
{
return
r
.
Create
(
ctx
,
name
,
obj
,
includeUninitialized
)
return
r
.
Create
(
ctx
,
name
,
obj
,
rest
.
AdmissionToValidateObjectFunc
(
validatingAdmission
,
admissionAttributes
),
includeUninitialized
,
)
})
if
err
!=
nil
{
scope
.
err
(
err
,
w
,
req
)
...
...
@@ -144,19 +150,19 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object
}
// CreateNamedResource returns a function that will handle a resource creation with name.
func
CreateNamedResource
(
r
rest
.
NamedCreater
,
scope
RequestScope
,
typer
runtime
.
ObjectTyper
,
admit
admission
.
Interface
)
http
.
HandlerFunc
{
return
createHandler
(
r
,
scope
,
typer
,
admit
,
true
)
func
CreateNamedResource
(
r
rest
.
NamedCreater
,
scope
RequestScope
,
typer
runtime
.
ObjectTyper
,
mutatingAdmission
admission
.
Interface
,
validatingAdmission
admission
.
Validation
Interface
)
http
.
HandlerFunc
{
return
createHandler
(
r
,
scope
,
typer
,
mutatingAdmission
,
validatingAdmission
,
true
)
}
// CreateResource returns a function that will handle a resource creation.
func
CreateResource
(
r
rest
.
Creater
,
scope
RequestScope
,
typer
runtime
.
ObjectTyper
,
admit
admission
.
Interface
)
http
.
HandlerFunc
{
return
createHandler
(
&
namedCreaterAdapter
{
r
},
scope
,
typer
,
admit
,
false
)
func
CreateResource
(
r
rest
.
Creater
,
scope
RequestScope
,
typer
runtime
.
ObjectTyper
,
mutatingAdmission
admission
.
Interface
,
validatingAdmission
admission
.
Validation
Interface
)
http
.
HandlerFunc
{
return
createHandler
(
&
namedCreaterAdapter
{
r
},
scope
,
typer
,
mutatingAdmission
,
validatingAdmission
,
false
)
}
type
namedCreaterAdapter
struct
{
rest
.
Creater
}
func
(
c
*
namedCreaterAdapter
)
Create
(
ctx
request
.
Context
,
name
string
,
obj
runtime
.
Object
,
includeUninitialized
bool
)
(
runtime
.
Object
,
error
)
{
return
c
.
Creater
.
Create
(
ctx
,
obj
,
includeUninitialized
)
func
(
c
*
namedCreaterAdapter
)
Create
(
ctx
request
.
Context
,
name
string
,
obj
runtime
.
Object
,
createValidatingAdmission
rest
.
ValidateObjectFunc
,
includeUninitialized
bool
)
(
runtime
.
Object
,
error
)
{
return
c
.
Creater
.
Create
(
ctx
,
obj
,
createValidatingAdmission
,
includeUninitialized
)
}
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/delete.go
View file @
02e16cb2
...
...
@@ -34,7 +34,8 @@ import (
)
// DeleteResource returns a function that will handle a resource deletion
func
DeleteResource
(
r
rest
.
GracefulDeleter
,
allowsOptions
bool
,
scope
RequestScope
,
admit
admission
.
Interface
)
http
.
HandlerFunc
{
// TODO admission here becomes solely validating admission
func
DeleteResource
(
r
rest
.
GracefulDeleter
,
allowsOptions
bool
,
scope
RequestScope
,
mutatingAdmission
admission
.
Interface
,
validatingAdmission
admission
.
ValidationInterface
)
http
.
HandlerFunc
{
return
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
// For performance tracking purposes.
trace
:=
utiltrace
.
New
(
"Delete "
+
req
.
URL
.
Path
)
...
...
@@ -93,10 +94,19 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
}
trace
.
Step
(
"About to check admission control"
)
if
admit
!=
nil
&&
admit
.
Handles
(
admission
.
Delete
)
{
if
mutatingAdmission
!=
nil
&&
mutatingAdmission
.
Handles
(
admission
.
Delete
)
{
userInfo
,
_
:=
request
.
UserFrom
(
ctx
)
err
=
admit
.
Admit
(
admission
.
NewAttributesRecord
(
nil
,
nil
,
scope
.
Kind
,
namespace
,
name
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Delete
,
userInfo
))
err
=
mutatingAdmission
.
Admit
(
admission
.
NewAttributesRecord
(
nil
,
nil
,
scope
.
Kind
,
namespace
,
name
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Delete
,
userInfo
))
if
err
!=
nil
{
scope
.
err
(
err
,
w
,
req
)
return
}
}
if
validatingAdmission
!=
nil
&&
validatingAdmission
.
Handles
(
admission
.
Delete
)
{
userInfo
,
_
:=
request
.
UserFrom
(
ctx
)
err
=
validatingAdmission
.
Validate
(
admission
.
NewAttributesRecord
(
nil
,
nil
,
scope
.
Kind
,
namespace
,
name
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Delete
,
userInfo
))
if
err
!=
nil
{
scope
.
err
(
err
,
w
,
req
)
return
...
...
@@ -157,7 +167,7 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
}
// DeleteCollection returns a function that will handle a collection deletion
func
DeleteCollection
(
r
rest
.
CollectionDeleter
,
checkBody
bool
,
scope
RequestScope
,
admit
admission
.
Interface
)
http
.
HandlerFunc
{
func
DeleteCollection
(
r
rest
.
CollectionDeleter
,
checkBody
bool
,
scope
RequestScope
,
mutatingAdmission
admission
.
Interface
,
validatingAdmission
admission
.
Validation
Interface
)
http
.
HandlerFunc
{
return
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
// TODO: we either want to remove timeout or document it (if we document, move timeout out of this function and declare it in api_installer)
timeout
:=
parseTimeout
(
req
.
URL
.
Query
()
.
Get
(
"timeout"
))
...
...
@@ -171,10 +181,19 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
ctx
:=
scope
.
ContextFunc
(
req
)
ctx
=
request
.
WithNamespace
(
ctx
,
namespace
)
if
admit
!=
nil
&&
admit
.
Handles
(
admission
.
Delete
)
{
if
mutatingAdmission
!=
nil
&&
mutatingAdmission
.
Handles
(
admission
.
Delete
)
{
userInfo
,
_
:=
request
.
UserFrom
(
ctx
)
err
=
mutatingAdmission
.
Admit
(
admission
.
NewAttributesRecord
(
nil
,
nil
,
scope
.
Kind
,
namespace
,
""
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Delete
,
userInfo
))
if
err
!=
nil
{
scope
.
err
(
err
,
w
,
req
)
return
}
}
if
validatingAdmission
!=
nil
&&
validatingAdmission
.
Handles
(
admission
.
Delete
)
{
userInfo
,
_
:=
request
.
UserFrom
(
ctx
)
err
=
admit
.
Admit
(
admission
.
NewAttributesRecord
(
nil
,
nil
,
scope
.
Kind
,
namespace
,
""
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Delete
,
userInfo
))
err
=
validatingAdmission
.
Validate
(
admission
.
NewAttributesRecord
(
nil
,
nil
,
scope
.
Kind
,
namespace
,
""
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Delete
,
userInfo
))
if
err
!=
nil
{
scope
.
err
(
err
,
w
,
req
)
return
...
...
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go
View file @
02e16cb2
...
...
@@ -33,7 +33,7 @@ import (
)
// UpdateResource returns a function that will handle a resource update
func
UpdateResource
(
r
rest
.
Updater
,
scope
RequestScope
,
typer
runtime
.
ObjectTyper
,
admit
admission
.
Interface
)
http
.
HandlerFunc
{
func
UpdateResource
(
r
rest
.
Updater
,
scope
RequestScope
,
typer
runtime
.
ObjectTyper
,
mutatingAdmission
admission
.
Interface
,
validatingAdmission
admission
.
Validation
Interface
)
http
.
HandlerFunc
{
return
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
// For performance tracking purposes.
trace
:=
utiltrace
.
New
(
"Update "
+
req
.
URL
.
Path
)
...
...
@@ -86,18 +86,25 @@ func UpdateResource(r rest.Updater, scope RequestScope, typer runtime.ObjectType
return
}
userInfo
,
_
:=
request
.
UserFrom
(
ctx
)
staticAdmissionAttributes
:=
admission
.
NewAttributesRecord
(
nil
,
nil
,
scope
.
Kind
,
namespace
,
name
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Update
,
userInfo
)
var
transformers
[]
rest
.
TransformFunc
if
admit
!=
nil
&&
admit
.
Handles
(
admission
.
Update
)
{
if
mutatingAdmission
!=
nil
&&
mutatingAdmission
.
Handles
(
admission
.
Update
)
{
transformers
=
append
(
transformers
,
func
(
ctx
request
.
Context
,
newObj
,
oldObj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
userInfo
,
_
:=
request
.
UserFrom
(
ctx
)
return
newObj
,
admit
.
Admit
(
admission
.
NewAttributesRecord
(
newObj
,
oldObj
,
scope
.
Kind
,
namespace
,
name
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Update
,
userInfo
))
return
newObj
,
mutatingAdmission
.
Admit
(
admission
.
NewAttributesRecord
(
newObj
,
oldObj
,
scope
.
Kind
,
namespace
,
name
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Update
,
userInfo
))
})
}
trace
.
Step
(
"About to store object in database"
)
wasCreated
:=
false
result
,
err
:=
finishRequest
(
timeout
,
func
()
(
runtime
.
Object
,
error
)
{
obj
,
created
,
err
:=
r
.
Update
(
ctx
,
name
,
rest
.
DefaultUpdatedObjectInfo
(
obj
,
transformers
...
))
obj
,
created
,
err
:=
r
.
Update
(
ctx
,
name
,
rest
.
DefaultUpdatedObjectInfo
(
obj
,
transformers
...
),
rest
.
AdmissionToValidateObjectFunc
(
validatingAdmission
,
staticAdmissionAttributes
),
rest
.
AdmissionToValidateObjectUpdateFunc
(
validatingAdmission
,
staticAdmissionAttributes
),
)
wasCreated
=
created
return
obj
,
err
})
...
...
staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go
View file @
02e16cb2
...
...
@@ -52,6 +52,16 @@ import (
// object.
type
ObjectFunc
func
(
obj
runtime
.
Object
)
error
// ValidateObjectFunc is a function to act on a given object. An error may be returned
// if the hook cannot be completed. An ObjectFunc may NOT transform the provided
// object.
type
ValidateObjectFunc
func
(
obj
runtime
.
Object
)
error
// ValidateObjectUpdateFunc is a function to act on a given object and its predecessor.
// An error may be returned if the hook cannot be completed. An UpdateObjectFunc
// may NOT transform the provided object.
type
ValidateObjectUpdateFunc
func
(
obj
,
old
runtime
.
Object
)
error
// GenericStore interface can be used for type assertions when we need to access the underlying strategies.
type
GenericStore
interface
{
GetCreateStrategy
()
rest
.
RESTCreateStrategy
...
...
@@ -148,11 +158,13 @@ type Store struct {
// AfterCreate implements a further operation to run after a resource is
// created and before it is decorated, optional.
AfterCreate
ObjectFunc
// UpdateStrategy implements resource-specific behavior during updates.
UpdateStrategy
rest
.
RESTUpdateStrategy
// AfterUpdate implements a further operation to run after a resource is
// updated and before it is decorated, optional.
AfterUpdate
ObjectFunc
// DeleteStrategy implements resource-specific behavior during deletion.
DeleteStrategy
rest
.
RESTDeleteStrategy
// AfterDelete implements a further operation to run after a resource is
...
...
@@ -303,10 +315,18 @@ func (e *Store) ListPredicate(ctx genericapirequest.Context, p storage.Selection
}
// Create inserts a new item according to the unique key from the object.
func
(
e
*
Store
)
Create
(
ctx
genericapirequest
.
Context
,
obj
runtime
.
Object
,
includeUninitialized
bool
)
(
runtime
.
Object
,
error
)
{
func
(
e
*
Store
)
Create
(
ctx
genericapirequest
.
Context
,
obj
runtime
.
Object
,
createValidation
ValidateObjectFunc
,
includeUninitialized
bool
)
(
runtime
.
Object
,
error
)
{
if
err
:=
rest
.
BeforeCreate
(
e
.
CreateStrategy
,
ctx
,
obj
);
err
!=
nil
{
return
nil
,
err
}
// at this point we have a fully formed object. It is time to call the validators that the apiserver
// handling chain wants to enforce.
if
createValidation
!=
nil
{
if
err
:=
createValidation
(
obj
.
DeepCopyObject
());
err
!=
nil
{
return
nil
,
err
}
}
name
,
err
:=
e
.
ObjectNameFunc
(
obj
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -494,7 +514,7 @@ func (e *Store) deleteWithoutFinalizers(ctx genericapirequest.Context, name, key
// Update performs an atomic update and set of the object. Returns the result of the update
// or an error. If the registry allows create-on-update, the create flow will be executed.
// A bool is returned along with the object and any errors, to indicate object creation.
func
(
e
*
Store
)
Update
(
ctx
genericapirequest
.
Context
,
name
string
,
objInfo
rest
.
UpdatedObjectInfo
)
(
runtime
.
Object
,
bool
,
error
)
{
func
(
e
*
Store
)
Update
(
ctx
genericapirequest
.
Context
,
name
string
,
objInfo
rest
.
UpdatedObjectInfo
,
createValidation
ValidateObjectFunc
,
updateValidation
ValidateObjectUpdateFunc
)
(
runtime
.
Object
,
bool
,
error
)
{
key
,
err
:=
e
.
KeyFunc
(
ctx
,
name
)
if
err
!=
nil
{
return
nil
,
false
,
err
...
...
@@ -544,10 +564,18 @@ func (e *Store) Update(ctx genericapirequest.Context, name string, objInfo rest.
if
err
:=
rest
.
BeforeCreate
(
e
.
CreateStrategy
,
ctx
,
obj
);
err
!=
nil
{
return
nil
,
nil
,
err
}
// at this point we have a fully formed object. It is time to call the validators that the apiserver
// handling chain wants to enforce.
if
createValidation
!=
nil
{
if
err
:=
createValidation
(
obj
.
DeepCopyObject
());
err
!=
nil
{
return
nil
,
nil
,
err
}
}
ttl
,
err
:=
e
.
calculateTTL
(
obj
,
0
,
false
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
return
obj
,
&
ttl
,
nil
}
...
...
@@ -582,6 +610,13 @@ func (e *Store) Update(ctx genericapirequest.Context, name string, objInfo rest.
if
err
:=
rest
.
BeforeUpdate
(
e
.
UpdateStrategy
,
ctx
,
obj
,
existing
);
err
!=
nil
{
return
nil
,
nil
,
err
}
// at this point we have a fully formed object. It is time to call the validators that the apiserver
// handling chain wants to enforce.
if
updateValidation
!=
nil
{
if
err
:=
updateValidation
(
obj
.
DeepCopyObject
(),
existing
.
DeepCopyObject
());
err
!=
nil
{
return
nil
,
nil
,
err
}
}
if
e
.
shouldDeleteDuringUpdate
(
ctx
,
key
,
obj
,
existing
)
{
deleteObj
=
obj
return
nil
,
nil
,
errEmptiedFinalizers
...
...
staging/src/k8s.io/apiserver/pkg/registry/rest/create.go
View file @
02e16cb2
...
...
@@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/admission"
genericapirequest
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/storage/names"
...
...
@@ -151,3 +152,24 @@ type NamespaceScopedStrategy interface {
// NamespaceScoped returns if the object must be in a namespace.
NamespaceScoped
()
bool
}
// AdmissionToValidateObjectFunc converts validating admission to a rest validate object func
func
AdmissionToValidateObjectFunc
(
validatingAdmission
admission
.
ValidationInterface
,
staticAttributes
admission
.
Attributes
)
ValidateObjectFunc
{
return
func
(
obj
runtime
.
Object
)
error
{
finalAttributes
:=
admission
.
NewAttributesRecord
(
obj
,
staticAttributes
.
GetOldObject
(),
staticAttributes
.
GetKind
(),
staticAttributes
.
GetNamespace
(),
staticAttributes
.
GetName
(),
staticAttributes
.
GetResource
(),
staticAttributes
.
GetSubresource
(),
staticAttributes
.
GetOperation
(),
staticAttributes
.
GetUserInfo
(),
)
if
!
validatingAdmission
.
Handles
(
finalAttributes
.
GetOperation
())
{
return
nil
}
return
validatingAdmission
.
Validate
(
finalAttributes
)
}
}
staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go
View file @
02e16cb2
...
...
@@ -192,7 +192,7 @@ type Creater interface {
// Create creates a new version of a resource. If includeUninitialized is set, the object may be returned
// without completing initialization.
Create
(
ctx
genericapirequest
.
Context
,
obj
runtime
.
Object
,
includeUninitialized
bool
)
(
runtime
.
Object
,
error
)
Create
(
ctx
genericapirequest
.
Context
,
obj
runtime
.
Object
,
createValidation
ValidateObjectFunc
,
includeUninitialized
bool
)
(
runtime
.
Object
,
error
)
}
// NamedCreater is an object that can create an instance of a RESTful object using a name parameter.
...
...
@@ -205,7 +205,7 @@ type NamedCreater interface {
// This is needed for create operations on subresources which include the name of the parent
// resource in the path. If includeUninitialized is set, the object may be returned without
// completing initialization.
Create
(
ctx
genericapirequest
.
Context
,
name
string
,
obj
runtime
.
Object
,
includeUninitialized
bool
)
(
runtime
.
Object
,
error
)
Create
(
ctx
genericapirequest
.
Context
,
name
string
,
obj
runtime
.
Object
,
createValidation
ValidateObjectFunc
,
includeUninitialized
bool
)
(
runtime
.
Object
,
error
)
}
// UpdatedObjectInfo provides information about an updated object to an Updater.
...
...
@@ -221,6 +221,16 @@ type UpdatedObjectInfo interface {
UpdatedObject
(
ctx
genericapirequest
.
Context
,
oldObj
runtime
.
Object
)
(
newObj
runtime
.
Object
,
err
error
)
}
// ValidateObjectFunc is a function to act on a given object. An error may be returned
// if the hook cannot be completed. An ObjectFunc may NOT transform the provided
// object.
type
ValidateObjectFunc
func
(
obj
runtime
.
Object
)
error
// ValidateObjectUpdateFunc is a function to act on a given object and its predecessor.
// An error may be returned if the hook cannot be completed. An UpdateObjectFunc
// may NOT transform the provided object.
type
ValidateObjectUpdateFunc
func
(
obj
,
old
runtime
.
Object
)
error
// Updater is an object that can update an instance of a RESTful object.
type
Updater
interface
{
// New returns an empty object that can be used with Update after request data has been put into it.
...
...
@@ -230,14 +240,14 @@ type Updater interface {
// Update finds a resource in the storage and updates it. Some implementations
// may allow updates creates the object - they should set the created boolean
// to true.
Update
(
ctx
genericapirequest
.
Context
,
name
string
,
objInfo
UpdatedObjectInfo
)
(
runtime
.
Object
,
bool
,
error
)
Update
(
ctx
genericapirequest
.
Context
,
name
string
,
objInfo
UpdatedObjectInfo
,
createValidation
ValidateObjectFunc
,
updateValidation
ValidateObjectUpdateFunc
)
(
runtime
.
Object
,
bool
,
error
)
}
// CreaterUpdater is a storage object that must support both create and update.
// Go prevents embedded interfaces that implement the same method.
type
CreaterUpdater
interface
{
Creater
Update
(
ctx
genericapirequest
.
Context
,
name
string
,
objInfo
UpdatedObjectInfo
)
(
runtime
.
Object
,
bool
,
error
)
Update
(
ctx
genericapirequest
.
Context
,
name
string
,
objInfo
UpdatedObjectInfo
,
createValidation
ValidateObjectFunc
,
updateValidation
ValidateObjectUpdateFunc
)
(
runtime
.
Object
,
bool
,
error
)
}
// CreaterUpdater must satisfy the Updater interface.
...
...
staging/src/k8s.io/apiserver/pkg/registry/rest/update.go
View file @
02e16cb2
...
...
@@ -26,6 +26,7 @@ import (
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/admission"
genericapirequest
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/features"
utilfeature
"k8s.io/apiserver/pkg/util/feature"
...
...
@@ -229,3 +230,24 @@ func (i *wrappedUpdatedObjectInfo) UpdatedObject(ctx genericapirequest.Context,
return
newObj
,
nil
}
// AdmissionToValidateObjectUpdateFunc converts validating admission to a rest validate object update func
func
AdmissionToValidateObjectUpdateFunc
(
validatingAdmission
admission
.
ValidationInterface
,
staticAttributes
admission
.
Attributes
)
ValidateObjectUpdateFunc
{
return
func
(
obj
,
old
runtime
.
Object
)
error
{
finalAttributes
:=
admission
.
NewAttributesRecord
(
obj
,
old
,
staticAttributes
.
GetKind
(),
staticAttributes
.
GetNamespace
(),
staticAttributes
.
GetName
(),
staticAttributes
.
GetResource
(),
staticAttributes
.
GetSubresource
(),
staticAttributes
.
GetOperation
(),
staticAttributes
.
GetUserInfo
(),
)
if
!
validatingAdmission
.
Handles
(
finalAttributes
.
GetOperation
())
{
return
nil
}
return
validatingAdmission
.
Validate
(
finalAttributes
)
}
}
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