// 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 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) if kerr != nil { return kerr } if strategy.NamespaceScoped() { if !api.ValidNamespace(ctx, objectMeta) { return errors.NewBadRequest("the namespace of the provided object does not match the namespace sent on the request") } } else { objectMeta.Namespace = api.NamespaceNone } objectMeta.DeletionTimestamp = nil objectMeta.DeletionGracePeriodSeconds = nil strategy.PrepareForCreate(obj) api.FillObjectMetaSystemFields(ctx, objectMeta) api.GenerateName(strategy, objectMeta) if errs := strategy.Validate(ctx, obj); len(errs) > 0 { return errors.NewInvalid(kind, objectMeta.Name, errs) } // Custom validation (including name validation) passed // Now run common validation on object meta // Do this *after* custom validation so that specific error messages are shown whenever possible if errs := validation.ValidateObjectMeta(objectMeta, strategy.NamespaceScoped(), validation.ValidatePathSegmentName); len(errs) > 0 { return errors.NewInvalid(kind, objectMeta.Name, errs) } return nil }
// TestFillObjectMetaSystemFields validates that system populated fields are set on an object func TestFillObjectMetaSystemFields(t *testing.T) { ctx := api.NewDefaultContext() resource := api.ObjectMeta{} api.FillObjectMetaSystemFields(ctx, &resource) if resource.CreationTimestamp.Time.IsZero() { t.Errorf("resource.CreationTimestamp is zero") } else if len(resource.UID) == 0 { t.Errorf("resource.UID missing") } }
// TestHasObjectMetaSystemFieldValues validates that true is returned if and only if all fields are populated func TestHasObjectMetaSystemFieldValues(t *testing.T) { ctx := api.NewDefaultContext() resource := api.ObjectMeta{} if api.HasObjectMetaSystemFieldValues(&resource) { t.Errorf("the resource does not have all fields yet populated, but incorrectly reports it does") } api.FillObjectMetaSystemFields(ctx, &resource) if !api.HasObjectMetaSystemFieldValues(&resource) { t.Errorf("the resource does have all fields populated, but incorrectly reports it does not") } }
// 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 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) if kerr != nil { return kerr } if strategy.NamespaceScoped() { if !api.ValidNamespace(ctx, objectMeta) { return errors.NewBadRequest("the namespace of the provided object does not match the namespace sent on the request") } } else { objectMeta.Namespace = api.NamespaceNone } strategy.PrepareForCreate(obj) api.FillObjectMetaSystemFields(ctx, objectMeta) api.GenerateName(strategy, objectMeta) if errs := strategy.Validate(ctx, obj); len(errs) > 0 { return errors.NewInvalid(kind, objectMeta.Name, errs) } return nil }