mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 22:46:12 +00:00
Merge pull request #5970 from thockin/rest_cleanups
Rest hooks for Create and Update
This commit is contained in:
commit
f9aa0d5851
@ -34,16 +34,17 @@ type RESTCreateStrategy interface {
|
||||
|
||||
// NamespaceScoped returns true if the object must be within a namespace.
|
||||
NamespaceScoped() bool
|
||||
// ResetBeforeCreate is invoked on create before validation to remove any fields
|
||||
// that may not be persisted.
|
||||
ResetBeforeCreate(obj runtime.Object)
|
||||
// PrepareForCreate is invoked on create before validation to normalize
|
||||
// the object. For example: remove fields that are not to be persisted,
|
||||
// sort order-insensitive list fields, etc.
|
||||
PrepareForCreate(obj runtime.Object)
|
||||
// Validate is invoked after default fields in the object have been filled in before
|
||||
// the object is persisted.
|
||||
Validate(obj runtime.Object) fielderrors.ValidationErrorList
|
||||
}
|
||||
|
||||
// BeforeCreate ensures that common operations for all resources are performed on creation. It only returns
|
||||
// errors that can be converted to api.Status. It invokes ResetBeforeCreate, then GenerateName, then Validate.
|
||||
// errors that can be converted to api.Status. It invokes PrepareForCreate, then GenerateName, then Validate.
|
||||
// It returns nil if the object should be created.
|
||||
func BeforeCreate(strategy RESTCreateStrategy, ctx api.Context, obj runtime.Object) error {
|
||||
objectMeta, kind, kerr := objectMetaAndKind(strategy, obj)
|
||||
@ -58,7 +59,7 @@ func BeforeCreate(strategy RESTCreateStrategy, ctx api.Context, obj runtime.Obje
|
||||
} else {
|
||||
objectMeta.Namespace = api.NamespaceNone
|
||||
}
|
||||
strategy.ResetBeforeCreate(obj)
|
||||
strategy.PrepareForCreate(obj)
|
||||
api.FillObjectMetaSystemFields(ctx, objectMeta)
|
||||
api.GenerateName(strategy, objectMeta)
|
||||
|
||||
|
@ -60,12 +60,20 @@ func (svcStrategy) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ResetBeforeCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (svcStrategy) ResetBeforeCreate(obj runtime.Object) {
|
||||
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (svcStrategy) PrepareForCreate(obj runtime.Object) {
|
||||
service := obj.(*api.Service)
|
||||
service.Status = api.ServiceStatus{}
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (svcStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
// TODO: once service has a status sub-resource we can enable this.
|
||||
//newService := obj.(*api.Service)
|
||||
//oldService := old.(*api.Service)
|
||||
//newService.Status = oldService.Status
|
||||
}
|
||||
|
||||
// Validate validates a new service.
|
||||
func (svcStrategy) Validate(obj runtime.Object) fielderrors.ValidationErrorList {
|
||||
service := obj.(*api.Service)
|
||||
|
@ -33,6 +33,10 @@ type RESTUpdateStrategy interface {
|
||||
NamespaceScoped() bool
|
||||
// AllowCreateOnUpdate returns true if the object can be created by a PUT.
|
||||
AllowCreateOnUpdate() bool
|
||||
// PrepareForUpdate is invoked on update before validation to normalize
|
||||
// the object. For example: remove fields that are not to be persisted,
|
||||
// sort order-insensitive list fields, etc.
|
||||
PrepareForUpdate(obj, old runtime.Object)
|
||||
// ValidateUpdate is invoked after default fields in the object have been filled in before
|
||||
// the object is persisted.
|
||||
ValidateUpdate(obj, old runtime.Object) fielderrors.ValidationErrorList
|
||||
@ -53,6 +57,7 @@ func BeforeUpdate(strategy RESTUpdateStrategy, ctx api.Context, obj, old runtime
|
||||
} else {
|
||||
objectMeta.Namespace = api.NamespaceNone
|
||||
}
|
||||
strategy.PrepareForUpdate(obj, old)
|
||||
if errs := strategy.ValidateUpdate(obj, old); len(errs) > 0 {
|
||||
return errors.NewInvalid(kind, objectMeta.Name, errs)
|
||||
}
|
||||
|
@ -42,12 +42,20 @@ func (rcStrategy) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ResetBeforeCreate clears the status of a replication controller before creation.
|
||||
func (rcStrategy) ResetBeforeCreate(obj runtime.Object) {
|
||||
// PrepareForCreate clears the status of a replication controller before creation.
|
||||
func (rcStrategy) PrepareForCreate(obj runtime.Object) {
|
||||
controller := obj.(*api.ReplicationController)
|
||||
controller.Status = api.ReplicationControllerStatus{}
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (rcStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
// TODO: once RC has a status sub-resource we can enable this.
|
||||
//newController := obj.(*api.ReplicationController)
|
||||
//oldController := old.(*api.ReplicationController)
|
||||
//newController.Status = oldController.Status
|
||||
}
|
||||
|
||||
// Validate validates a new replication controller.
|
||||
func (rcStrategy) Validate(obj runtime.Object) fielderrors.ValidationErrorList {
|
||||
controller := obj.(*api.ReplicationController)
|
||||
|
@ -43,11 +43,17 @@ func (endpointsStrategy) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ResetBeforeCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (endpointsStrategy) ResetBeforeCreate(obj runtime.Object) {
|
||||
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (endpointsStrategy) PrepareForCreate(obj runtime.Object) {
|
||||
_ = obj.(*api.Endpoints)
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (endpointsStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
_ = obj.(*api.Endpoints)
|
||||
_ = old.(*api.Endpoints)
|
||||
}
|
||||
|
||||
// Validate validates a new endpoints.
|
||||
func (endpointsStrategy) Validate(obj runtime.Object) fielderrors.ValidationErrorList {
|
||||
return validation.ValidateEndpoints(obj.(*api.Endpoints))
|
||||
|
@ -43,7 +43,8 @@ type testRESTStrategy struct {
|
||||
func (t *testRESTStrategy) NamespaceScoped() bool { return t.namespaceScoped }
|
||||
func (t *testRESTStrategy) AllowCreateOnUpdate() bool { return t.allowCreateOnUpdate }
|
||||
|
||||
func (t *testRESTStrategy) ResetBeforeCreate(obj runtime.Object) {}
|
||||
func (t *testRESTStrategy) PrepareForCreate(obj runtime.Object) {}
|
||||
func (t *testRESTStrategy) PrepareForUpdate(obj, old runtime.Object) {}
|
||||
func (t *testRESTStrategy) Validate(obj runtime.Object) fielderrors.ValidationErrorList {
|
||||
return nil
|
||||
}
|
||||
|
@ -53,12 +53,19 @@ func (nodeStrategy) AllowCreateOnUpdate() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ResetBeforeCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (nodeStrategy) ResetBeforeCreate(obj runtime.Object) {
|
||||
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (nodeStrategy) PrepareForCreate(obj runtime.Object) {
|
||||
_ = obj.(*api.Node)
|
||||
// Nodes allow *all* fields, including status, to be set.
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (nodeStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
_ = obj.(*api.Node)
|
||||
_ = old.(*api.Node)
|
||||
// Nodes allow *all* fields, including status, to be set.
|
||||
}
|
||||
|
||||
// Validate validates a new node.
|
||||
func (nodeStrategy) Validate(obj runtime.Object) fielderrors.ValidationErrorList {
|
||||
node := obj.(*api.Node)
|
||||
|
@ -43,8 +43,8 @@ func (namespaceStrategy) NamespaceScoped() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// ResetBeforeCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (namespaceStrategy) ResetBeforeCreate(obj runtime.Object) {
|
||||
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (namespaceStrategy) PrepareForCreate(obj runtime.Object) {
|
||||
// on create, status is active
|
||||
namespace := obj.(*api.Namespace)
|
||||
namespace.Status = api.NamespaceStatus{
|
||||
@ -68,6 +68,14 @@ func (namespaceStrategy) ResetBeforeCreate(obj runtime.Object) {
|
||||
}
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (namespaceStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
newNamespace := obj.(*api.Namespace)
|
||||
oldNamespace := old.(*api.Namespace)
|
||||
newNamespace.Spec.Finalizers = oldNamespace.Spec.Finalizers
|
||||
newNamespace.Status = oldNamespace.Status
|
||||
}
|
||||
|
||||
// Validate validates a new namespace.
|
||||
func (namespaceStrategy) Validate(obj runtime.Object) fielderrors.ValidationErrorList {
|
||||
namespace := obj.(*api.Namespace)
|
||||
@ -90,6 +98,12 @@ type namespaceStatusStrategy struct {
|
||||
|
||||
var StatusStrategy = namespaceStatusStrategy{Strategy}
|
||||
|
||||
func (namespaceStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
newNamespace := obj.(*api.Namespace)
|
||||
oldNamespace := old.(*api.Namespace)
|
||||
newNamespace.Spec = oldNamespace.Spec
|
||||
}
|
||||
|
||||
func (namespaceStatusStrategy) ValidateUpdate(obj, old runtime.Object) fielderrors.ValidationErrorList {
|
||||
return validation.ValidateNamespaceStatusUpdate(obj.(*api.Namespace), old.(*api.Namespace))
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ func TestNamespaceStrategy(t *testing.T) {
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Status: api.NamespaceStatus{Phase: api.NamespaceTerminating},
|
||||
}
|
||||
Strategy.ResetBeforeCreate(namespace)
|
||||
Strategy.PrepareForCreate(namespace)
|
||||
if namespace.Status.Phase != api.NamespaceActive {
|
||||
t.Errorf("Namespaces do not allow setting phase on create")
|
||||
}
|
||||
|
@ -50,8 +50,8 @@ func (podStrategy) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ResetBeforeCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (podStrategy) ResetBeforeCreate(obj runtime.Object) {
|
||||
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (podStrategy) PrepareForCreate(obj runtime.Object) {
|
||||
pod := obj.(*api.Pod)
|
||||
pod.Status = api.PodStatus{
|
||||
Host: pod.Spec.Host,
|
||||
@ -59,6 +59,13 @@ func (podStrategy) ResetBeforeCreate(obj runtime.Object) {
|
||||
}
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (podStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
newPod := obj.(*api.Pod)
|
||||
oldPod := old.(*api.Pod)
|
||||
newPod.Status = oldPod.Status
|
||||
}
|
||||
|
||||
// Validate validates a new pod.
|
||||
func (podStrategy) Validate(obj runtime.Object) fielderrors.ValidationErrorList {
|
||||
pod := obj.(*api.Pod)
|
||||
@ -86,6 +93,12 @@ type podStatusStrategy struct {
|
||||
|
||||
var StatusStrategy = podStatusStrategy{Strategy}
|
||||
|
||||
func (podStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
newPod := obj.(*api.Pod)
|
||||
oldPod := old.(*api.Pod)
|
||||
newPod.Spec = oldPod.Spec
|
||||
}
|
||||
|
||||
func (podStatusStrategy) ValidateUpdate(obj, old runtime.Object) fielderrors.ValidationErrorList {
|
||||
// TODO: merge valid fields after update
|
||||
return validation.ValidatePodStatusUpdate(obj.(*api.Pod), old.(*api.Pod))
|
||||
|
@ -43,12 +43,19 @@ func (resourcequotaStrategy) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ResetBeforeCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (resourcequotaStrategy) ResetBeforeCreate(obj runtime.Object) {
|
||||
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
|
||||
func (resourcequotaStrategy) PrepareForCreate(obj runtime.Object) {
|
||||
resourcequota := obj.(*api.ResourceQuota)
|
||||
resourcequota.Status = api.ResourceQuotaStatus{}
|
||||
}
|
||||
|
||||
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
|
||||
func (resourcequotaStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
newResourcequota := obj.(*api.ResourceQuota)
|
||||
oldResourcequota := old.(*api.ResourceQuota)
|
||||
newResourcequota.Status = oldResourcequota.Status
|
||||
}
|
||||
|
||||
// Validate validates a new resourcequota.
|
||||
func (resourcequotaStrategy) Validate(obj runtime.Object) fielderrors.ValidationErrorList {
|
||||
resourcequota := obj.(*api.ResourceQuota)
|
||||
@ -71,6 +78,12 @@ type resourcequotaStatusStrategy struct {
|
||||
|
||||
var StatusStrategy = resourcequotaStatusStrategy{Strategy}
|
||||
|
||||
func (resourcequotaStatusStrategy) PrepareForUpdate(obj, old runtime.Object) {
|
||||
newResourcequota := obj.(*api.ResourceQuota)
|
||||
oldResourcequota := old.(*api.ResourceQuota)
|
||||
newResourcequota.Spec = oldResourcequota.Spec
|
||||
}
|
||||
|
||||
func (resourcequotaStatusStrategy) ValidateUpdate(obj, old runtime.Object) fielderrors.ValidationErrorList {
|
||||
return validation.ValidateResourceQuotaStatusUpdate(obj.(*api.ResourceQuota), old.(*api.ResourceQuota))
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ func TestResourceQuotaStrategy(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
Strategy.ResetBeforeCreate(resourceQuota)
|
||||
Strategy.PrepareForCreate(resourceQuota)
|
||||
if resourceQuota.Status.Used != nil {
|
||||
t.Errorf("ResourceQuota does not allow setting status on create")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user