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 {
...
@@ -61,6 +61,16 @@ type Interface interface {
Handles
(
operation
Operation
)
bool
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
// Operation is the type of resource operation being checked for admission control
type
Operation
string
type
Operation
string
...
...
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go
View file @
02e16cb2
...
@@ -34,7 +34,7 @@ import (
...
@@ -34,7 +34,7 @@ import (
utiltrace
"k8s.io/apiserver/pkg/util/trace"
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
)
{
return
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
// For performance tracking purposes.
// For performance tracking purposes.
trace
:=
utiltrace
.
New
(
"Create "
+
req
.
URL
.
Path
)
trace
:=
utiltrace
.
New
(
"Create "
+
req
.
URL
.
Path
)
...
@@ -93,10 +93,10 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object
...
@@ -93,10 +93,10 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object
ae
:=
request
.
AuditEventFrom
(
ctx
)
ae
:=
request
.
AuditEventFrom
(
ctx
)
audit
.
LogRequestObject
(
ae
,
obj
,
scope
.
Resource
,
scope
.
Subresource
,
scope
.
Serializer
)
audit
.
LogRequestObject
(
ae
,
obj
,
scope
.
Resource
,
scope
.
Subresource
,
scope
.
Serializer
)
if
admit
!=
nil
&&
admit
.
Handles
(
admission
.
Create
)
{
userInfo
,
_
:=
request
.
UserFrom
(
ctx
)
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
=
admit
.
Admit
(
admission
.
NewAttributesRecord
(
obj
,
nil
,
scope
.
Kind
,
namespace
,
name
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Create
,
userInfo
)
)
err
=
mutatingAdmission
.
Admit
(
admissionAttributes
)
if
err
!=
nil
{
if
err
!=
nil
{
scope
.
err
(
err
,
w
,
req
)
scope
.
err
(
err
,
w
,
req
)
return
return
...
@@ -108,7 +108,13 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object
...
@@ -108,7 +108,13 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object
trace
.
Step
(
"About to store object in database"
)
trace
.
Step
(
"About to store object in database"
)
result
,
err
:=
finishRequest
(
timeout
,
func
()
(
runtime
.
Object
,
error
)
{
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
{
if
err
!=
nil
{
scope
.
err
(
err
,
w
,
req
)
scope
.
err
(
err
,
w
,
req
)
...
@@ -144,19 +150,19 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object
...
@@ -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.
// 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
{
func
CreateNamedResource
(
r
rest
.
NamedCreater
,
scope
RequestScope
,
typer
runtime
.
ObjectTyper
,
mutatingAdmission
admission
.
Interface
,
validatingAdmission
admission
.
Validation
Interface
)
http
.
HandlerFunc
{
return
createHandler
(
r
,
scope
,
typer
,
admit
,
true
)
return
createHandler
(
r
,
scope
,
typer
,
mutatingAdmission
,
validatingAdmission
,
true
)
}
}
// CreateResource returns a function that will handle a resource creation.
// 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
{
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
,
admit
,
false
)
return
createHandler
(
&
namedCreaterAdapter
{
r
},
scope
,
typer
,
mutatingAdmission
,
validatingAdmission
,
false
)
}
}
type
namedCreaterAdapter
struct
{
type
namedCreaterAdapter
struct
{
rest
.
Creater
rest
.
Creater
}
}
func
(
c
*
namedCreaterAdapter
)
Create
(
ctx
request
.
Context
,
name
string
,
obj
runtime
.
Object
,
includeUninitialized
bool
)
(
runtime
.
Object
,
error
)
{
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
,
includeUninitialized
)
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 (
...
@@ -34,7 +34,8 @@ import (
)
)
// DeleteResource returns a function that will handle a resource deletion
// 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
)
{
return
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
// For performance tracking purposes.
// For performance tracking purposes.
trace
:=
utiltrace
.
New
(
"Delete "
+
req
.
URL
.
Path
)
trace
:=
utiltrace
.
New
(
"Delete "
+
req
.
URL
.
Path
)
...
@@ -93,10 +94,19 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
...
@@ -93,10 +94,19 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
}
}
trace
.
Step
(
"About to check admission control"
)
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
)
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
{
if
err
!=
nil
{
scope
.
err
(
err
,
w
,
req
)
scope
.
err
(
err
,
w
,
req
)
return
return
...
@@ -157,7 +167,7 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
...
@@ -157,7 +167,7 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
}
}
// DeleteCollection returns a function that will handle a collection deletion
// 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
)
{
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)
// 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"
))
timeout
:=
parseTimeout
(
req
.
URL
.
Query
()
.
Get
(
"timeout"
))
...
@@ -171,10 +181,19 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
...
@@ -171,10 +181,19 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
ctx
:=
scope
.
ContextFunc
(
req
)
ctx
:=
scope
.
ContextFunc
(
req
)
ctx
=
request
.
WithNamespace
(
ctx
,
namespace
)
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
)
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
{
if
err
!=
nil
{
scope
.
err
(
err
,
w
,
req
)
scope
.
err
(
err
,
w
,
req
)
return
return
...
...
staging/src/k8s.io/apiserver/pkg/endpoints/handlers/update.go
View file @
02e16cb2
...
@@ -33,7 +33,7 @@ import (
...
@@ -33,7 +33,7 @@ import (
)
)
// UpdateResource returns a function that will handle a resource update
// 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
)
{
return
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
// For performance tracking purposes.
// For performance tracking purposes.
trace
:=
utiltrace
.
New
(
"Update "
+
req
.
URL
.
Path
)
trace
:=
utiltrace
.
New
(
"Update "
+
req
.
URL
.
Path
)
...
@@ -86,18 +86,25 @@ func UpdateResource(r rest.Updater, scope RequestScope, typer runtime.ObjectType
...
@@ -86,18 +86,25 @@ func UpdateResource(r rest.Updater, scope RequestScope, typer runtime.ObjectType
return
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
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
)
{
transformers
=
append
(
transformers
,
func
(
ctx
request
.
Context
,
newObj
,
oldObj
runtime
.
Object
)
(
runtime
.
Object
,
error
)
{
userInfo
,
_
:=
request
.
UserFrom
(
ctx
)
return
newObj
,
mutatingAdmission
.
Admit
(
admission
.
NewAttributesRecord
(
newObj
,
oldObj
,
scope
.
Kind
,
namespace
,
name
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Update
,
userInfo
))
return
newObj
,
admit
.
Admit
(
admission
.
NewAttributesRecord
(
newObj
,
oldObj
,
scope
.
Kind
,
namespace
,
name
,
scope
.
Resource
,
scope
.
Subresource
,
admission
.
Update
,
userInfo
))
})
})
}
}
trace
.
Step
(
"About to store object in database"
)
trace
.
Step
(
"About to store object in database"
)
wasCreated
:=
false
wasCreated
:=
false
result
,
err
:=
finishRequest
(
timeout
,
func
()
(
runtime
.
Object
,
error
)
{
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
wasCreated
=
created
return
obj
,
err
return
obj
,
err
})
})
...
...
staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go
View file @
02e16cb2
...
@@ -52,6 +52,16 @@ import (
...
@@ -52,6 +52,16 @@ import (
// object.
// object.
type
ObjectFunc
func
(
obj
runtime
.
Object
)
error
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.
// GenericStore interface can be used for type assertions when we need to access the underlying strategies.
type
GenericStore
interface
{
type
GenericStore
interface
{
GetCreateStrategy
()
rest
.
RESTCreateStrategy
GetCreateStrategy
()
rest
.
RESTCreateStrategy
...
@@ -148,11 +158,13 @@ type Store struct {
...
@@ -148,11 +158,13 @@ type Store struct {
// AfterCreate implements a further operation to run after a resource is
// AfterCreate implements a further operation to run after a resource is
// created and before it is decorated, optional.
// created and before it is decorated, optional.
AfterCreate
ObjectFunc
AfterCreate
ObjectFunc
// UpdateStrategy implements resource-specific behavior during updates.
// UpdateStrategy implements resource-specific behavior during updates.
UpdateStrategy
rest
.
RESTUpdateStrategy
UpdateStrategy
rest
.
RESTUpdateStrategy
// AfterUpdate implements a further operation to run after a resource is
// AfterUpdate implements a further operation to run after a resource is
// updated and before it is decorated, optional.
// updated and before it is decorated, optional.
AfterUpdate
ObjectFunc
AfterUpdate
ObjectFunc
// DeleteStrategy implements resource-specific behavior during deletion.
// DeleteStrategy implements resource-specific behavior during deletion.
DeleteStrategy
rest
.
RESTDeleteStrategy
DeleteStrategy
rest
.
RESTDeleteStrategy
// AfterDelete implements a further operation to run after a resource is
// 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
...
@@ -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.
// 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
{
if
err
:=
rest
.
BeforeCreate
(
e
.
CreateStrategy
,
ctx
,
obj
);
err
!=
nil
{
return
nil
,
err
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
)
name
,
err
:=
e
.
ObjectNameFunc
(
obj
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -494,7 +514,7 @@ func (e *Store) deleteWithoutFinalizers(ctx genericapirequest.Context, name, key
...
@@ -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
// 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.
// 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.
// 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
)
key
,
err
:=
e
.
KeyFunc
(
ctx
,
name
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
false
,
err
return
nil
,
false
,
err
...
@@ -544,10 +564,18 @@ func (e *Store) Update(ctx genericapirequest.Context, name string, objInfo rest.
...
@@ -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
{
if
err
:=
rest
.
BeforeCreate
(
e
.
CreateStrategy
,
ctx
,
obj
);
err
!=
nil
{
return
nil
,
nil
,
err
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
)
ttl
,
err
:=
e
.
calculateTTL
(
obj
,
0
,
false
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
nil
,
err
return
nil
,
nil
,
err
}
}
return
obj
,
&
ttl
,
nil
return
obj
,
&
ttl
,
nil
}
}
...
@@ -582,6 +610,13 @@ func (e *Store) Update(ctx genericapirequest.Context, name string, objInfo rest.
...
@@ -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
{
if
err
:=
rest
.
BeforeUpdate
(
e
.
UpdateStrategy
,
ctx
,
obj
,
existing
);
err
!=
nil
{
return
nil
,
nil
,
err
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
)
{
if
e
.
shouldDeleteDuringUpdate
(
ctx
,
key
,
obj
,
existing
)
{
deleteObj
=
obj
deleteObj
=
obj
return
nil
,
nil
,
errEmptiedFinalizers
return
nil
,
nil
,
errEmptiedFinalizers
...
...
staging/src/k8s.io/apiserver/pkg/registry/rest/create.go
View file @
02e16cb2
...
@@ -25,6 +25,7 @@ import (
...
@@ -25,6 +25,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/admission"
genericapirequest
"k8s.io/apiserver/pkg/endpoints/request"
genericapirequest
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/storage/names"
"k8s.io/apiserver/pkg/storage/names"
...
@@ -151,3 +152,24 @@ type NamespaceScopedStrategy interface {
...
@@ -151,3 +152,24 @@ type NamespaceScopedStrategy interface {
// NamespaceScoped returns if the object must be in a namespace.
// NamespaceScoped returns if the object must be in a namespace.
NamespaceScoped
()
bool
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 {
...
@@ -192,7 +192,7 @@ type Creater interface {
// Create creates a new version of a resource. If includeUninitialized is set, the object may be returned
// Create creates a new version of a resource. If includeUninitialized is set, the object may be returned
// without completing initialization.
// 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.
// NamedCreater is an object that can create an instance of a RESTful object using a name parameter.
...
@@ -205,7 +205,7 @@ type NamedCreater interface {
...
@@ -205,7 +205,7 @@ type NamedCreater interface {
// This is needed for create operations on subresources which include the name of the parent
// 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
// resource in the path. If includeUninitialized is set, the object may be returned without
// completing initialization.
// 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.
// UpdatedObjectInfo provides information about an updated object to an Updater.
...
@@ -221,6 +221,16 @@ type UpdatedObjectInfo interface {
...
@@ -221,6 +221,16 @@ type UpdatedObjectInfo interface {
UpdatedObject
(
ctx
genericapirequest
.
Context
,
oldObj
runtime
.
Object
)
(
newObj
runtime
.
Object
,
err
error
)
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.
// Updater is an object that can update an instance of a RESTful object.
type
Updater
interface
{
type
Updater
interface
{
// New returns an empty object that can be used with Update after request data has been put into it.
// 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 {
...
@@ -230,14 +240,14 @@ type Updater interface {
// Update finds a resource in the storage and updates it. Some implementations
// Update finds a resource in the storage and updates it. Some implementations
// may allow updates creates the object - they should set the created boolean
// may allow updates creates the object - they should set the created boolean
// to true.
// 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.
// CreaterUpdater is a storage object that must support both create and update.
// Go prevents embedded interfaces that implement the same method.
// Go prevents embedded interfaces that implement the same method.
type
CreaterUpdater
interface
{
type
CreaterUpdater
interface
{
Creater
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.
// CreaterUpdater must satisfy the Updater interface.
...
...
staging/src/k8s.io/apiserver/pkg/registry/rest/update.go
View file @
02e16cb2
...
@@ -26,6 +26,7 @@ import (
...
@@ -26,6 +26,7 @@ import (
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/apiserver/pkg/admission"
genericapirequest
"k8s.io/apiserver/pkg/endpoints/request"
genericapirequest
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/features"
utilfeature
"k8s.io/apiserver/pkg/util/feature"
utilfeature
"k8s.io/apiserver/pkg/util/feature"
...
@@ -229,3 +230,24 @@ func (i *wrappedUpdatedObjectInfo) UpdatedObject(ctx genericapirequest.Context,
...
@@ -229,3 +230,24 @@ func (i *wrappedUpdatedObjectInfo) UpdatedObject(ctx genericapirequest.Context,
return
newObj
,
nil
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