// objectMetaAndKind retrieves kind and ObjectMeta from a runtime object, or returns an error. func objectMetaAndKind(typer runtime.ObjectTyper, obj runtime.Object) (*api.ObjectMeta, unversioned.GroupVersionKind, error) { objectMeta, err := api.ObjectMetaFor(obj) if err != nil { return nil, unversioned.GroupVersionKind{}, errors.NewInternalError(err) } kind, err := typer.ObjectKind(obj) if err != nil { return nil, unversioned.GroupVersionKind{}, errors.NewInternalError(err) } return objectMeta, kind, nil }
// 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. func BeforeUpdate(strategy RESTUpdateStrategy, ctx api.Context, obj, old 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.PrepareForUpdate(obj, old) // Ensure some common fields, like UID, are validated for all resources. errs, err := validateCommonFields(obj, old) if err != nil { return errors.NewInternalError(err) } errs = append(errs, strategy.ValidateUpdate(ctx, obj, old)...) if len(errs) > 0 { return errors.NewInvalid(kind.GroupKind(), objectMeta.Name, errs) } strategy.Canonicalize(obj) return nil }