Prevent resource version to custom resource on no-op writes
For ObjectMeta pruning, we round trip through marshalling and unmarshalling. If the ObjectMeta contained any strings with "" (or other fields with empty values) _and_ the respective fields are omitempty, those fields will be lost in the round trip process. This makes ObjectMeta after the no-op write different from the one before the write. Resource version is incremented every time data is written to etcd. Writes to etcd short-circuit if the bytes being written are identical to the bytes already present. So this ends up incrementing the resourceVersion even on no-op writes. The zero values are set in BeforeCreate and BeforeUpdate. This commit updates BeforeUpdate such that zero values are only set when the object does not have a zero value for the respective field. Kubernetes-commit: d691748aa64376e4b90ae2c01aca14d1be2b442c
This commit is contained in:
parent
1fcab2fe23
commit
4c15aa6ed8
|
|
@ -81,7 +81,7 @@ func BeforeCreate(strategy RESTCreateStrategy, ctx context.Context, obj runtime.
|
|||
if !ValidNamespace(ctx, objectMeta) {
|
||||
return errors.NewBadRequest("the namespace of the provided object does not match the namespace sent on the request")
|
||||
}
|
||||
} else {
|
||||
} else if len(objectMeta.GetNamespace()) > 0 {
|
||||
objectMeta.SetNamespace(metav1.NamespaceNone)
|
||||
}
|
||||
objectMeta.SetDeletionTimestamp(nil)
|
||||
|
|
@ -98,7 +98,9 @@ func BeforeCreate(strategy RESTCreateStrategy, ctx context.Context, obj runtime.
|
|||
}
|
||||
|
||||
// ClusterName is ignored and should not be saved
|
||||
objectMeta.SetClusterName("")
|
||||
if len(objectMeta.GetClusterName()) > 0 {
|
||||
objectMeta.SetClusterName("")
|
||||
}
|
||||
|
||||
if errs := strategy.Validate(ctx, obj); len(errs) > 0 {
|
||||
return errors.NewInvalid(kind.GroupKind(), objectMeta.GetName(), errs)
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ func validateCommonFields(obj, old runtime.Object, strategy RESTUpdateStrategy)
|
|||
// BeforeUpdate ensures that common operations for all resources are performed on update. It only returns
|
||||
// errors that can be converted to api.Status. It will invoke update validation with the provided existing
|
||||
// and updated objects.
|
||||
// It sets zero values only if the object does not have a zero value for the respective field.
|
||||
func BeforeUpdate(strategy RESTUpdateStrategy, ctx context.Context, obj, old runtime.Object) error {
|
||||
objectMeta, kind, kerr := objectMetaAndKind(strategy, obj)
|
||||
if kerr != nil {
|
||||
|
|
@ -92,9 +93,10 @@ func BeforeUpdate(strategy RESTUpdateStrategy, ctx context.Context, obj, old run
|
|||
if !ValidNamespace(ctx, objectMeta) {
|
||||
return errors.NewBadRequest("the namespace of the provided object does not match the namespace sent on the request")
|
||||
}
|
||||
} else {
|
||||
} else if len(objectMeta.GetNamespace()) > 0 {
|
||||
objectMeta.SetNamespace(metav1.NamespaceNone)
|
||||
}
|
||||
|
||||
// Ensure requests cannot update generation
|
||||
oldMeta, err := meta.Accessor(old)
|
||||
if err != nil {
|
||||
|
|
@ -111,7 +113,9 @@ func BeforeUpdate(strategy RESTUpdateStrategy, ctx context.Context, obj, old run
|
|||
strategy.PrepareForUpdate(ctx, obj, old)
|
||||
|
||||
// ClusterName is ignored and should not be saved
|
||||
objectMeta.SetClusterName("")
|
||||
if len(objectMeta.GetClusterName()) > 0 {
|
||||
objectMeta.SetClusterName("")
|
||||
}
|
||||
// Use the existing UID if none is provided
|
||||
if len(objectMeta.GetUID()) == 0 {
|
||||
objectMeta.SetUID(oldMeta.GetUID())
|
||||
|
|
|
|||
Loading…
Reference in New Issue