Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ObjectMetaFor #44281

Merged
merged 1 commit into from
Apr 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions pkg/api/v1/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func (meta *ObjectMeta) GetUID() types.UID { return meta.UID }
func (meta *ObjectMeta) SetUID(uid types.UID) { meta.UID = uid }
func (meta *ObjectMeta) GetResourceVersion() string { return meta.ResourceVersion }
func (meta *ObjectMeta) SetResourceVersion(version string) { meta.ResourceVersion = version }
func (meta *ObjectMeta) GetGeneration() int64 { return meta.Generation }
func (meta *ObjectMeta) SetGeneration(generation int64) { meta.Generation = generation }
func (meta *ObjectMeta) GetSelfLink() string { return meta.SelfLink }
func (meta *ObjectMeta) SetSelfLink(selfLink string) { meta.SelfLink = selfLink }
func (meta *ObjectMeta) GetCreationTimestamp() metav1.Time { return meta.CreationTimestamp }
Expand All @@ -45,6 +47,10 @@ func (meta *ObjectMeta) GetDeletionTimestamp() *metav1.Time { return meta.Deleti
func (meta *ObjectMeta) SetDeletionTimestamp(deletionTimestamp *metav1.Time) {
meta.DeletionTimestamp = deletionTimestamp
}
func (meta *ObjectMeta) GetDeletionGracePeriodSeconds() *int64 { return meta.DeletionGracePeriodSeconds }
func (meta *ObjectMeta) SetDeletionGracePeriodSeconds(deletionGracePeriodSeconds *int64) {
meta.DeletionGracePeriodSeconds = deletionGracePeriodSeconds
}
func (meta *ObjectMeta) GetLabels() map[string]string { return meta.Labels }
func (meta *ObjectMeta) SetLabels(labels map[string]string) { meta.Labels = labels }
func (meta *ObjectMeta) GetAnnotations() map[string]string { return meta.Annotations }
Expand Down
1 change: 1 addition & 0 deletions pkg/registry/core/service/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ go_test(
"//pkg/registry/core/service/portallocator:go_default_library",
"//pkg/registry/registrytest:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/api/meta",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/util/intstr",
Expand Down
13 changes: 11 additions & 2 deletions pkg/registry/core/service/rest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"testing"

"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
utilnet "k8s.io/apimachinery/pkg/util/net"
Expand Down Expand Up @@ -98,7 +99,11 @@ func TestServiceRegistryCreate(t *testing.T) {
t.Fatalf("Unexpected error: %v", err)
}
created_service := created_svc.(*api.Service)
if !metav1.HasObjectMetaSystemFieldValues(&created_service.ObjectMeta) {
objMeta, err := meta.Accessor(created_service)
if err != nil {
t.Fatal(err)
}
if !metav1.HasObjectMetaSystemFieldValues(objMeta) {
t.Errorf("storage did not populate object meta field values")
}
if created_service.Name != "foo" {
Expand Down Expand Up @@ -218,7 +223,11 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) {
t.Fatalf("Unexpected error: %v", err)
}
created_service := created_svc.(*api.Service)
if !metav1.HasObjectMetaSystemFieldValues(&created_service.ObjectMeta) {
objMeta, err := meta.Accessor(created_service)
if err != nil {
t.Fatal(err)
}
if !metav1.HasObjectMetaSystemFieldValues(objMeta) {
t.Errorf("storage did not populate object meta field values")
}
if created_service.Name != test.name {
Expand Down
126 changes: 78 additions & 48 deletions staging/src/k8s.io/apimachinery/pkg/api/validation/objectmeta.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"strings"

apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand Down Expand Up @@ -131,47 +132,60 @@ func ValidateImmutableField(newVal, oldVal interface{}, fldPath *field.Path) fie
// ValidateObjectMeta validates an object's metadata on creation. It expects that name generation has already
// been performed.
// It doesn't return an error for rootscoped resources with namespace, because namespace should already be cleared before.
func ValidateObjectMeta(meta *metav1.ObjectMeta, requiresNamespace bool, nameFn ValidateNameFunc, fldPath *field.Path) field.ErrorList {
func ValidateObjectMeta(objMeta *metav1.ObjectMeta, requiresNamespace bool, nameFn ValidateNameFunc, fldPath *field.Path) field.ErrorList {
metadata, err := meta.Accessor(objMeta)
if err != nil {
allErrs := field.ErrorList{}
allErrs = append(allErrs, field.Invalid(fldPath, objMeta, err.Error()))
return allErrs
}
return ValidateObjectMetaAccessor(metadata, requiresNamespace, nameFn, fldPath)
}

// ValidateObjectMeta validates an object's metadata on creation. It expects that name generation has already
// been performed.
// It doesn't return an error for rootscoped resources with namespace, because namespace should already be cleared before.
func ValidateObjectMetaAccessor(meta metav1.Object, requiresNamespace bool, nameFn ValidateNameFunc, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if len(meta.GenerateName) != 0 {
for _, msg := range nameFn(meta.GenerateName, true) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("generateName"), meta.GenerateName, msg))
if len(meta.GetGenerateName()) != 0 {
for _, msg := range nameFn(meta.GetGenerateName(), true) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("generateName"), meta.GetGenerateName(), msg))
}
}
// If the generated name validates, but the calculated value does not, it's a problem with generation, and we
// report it here. This may confuse users, but indicates a programming bug and still must be validated.
// If there are multiple fields out of which one is required then add an or as a separator
if len(meta.Name) == 0 {
if len(meta.GetName()) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("name"), "name or generateName is required"))
} else {
for _, msg := range nameFn(meta.Name, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), meta.Name, msg))
for _, msg := range nameFn(meta.GetName(), false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), meta.GetName(), msg))
}
}
if requiresNamespace {
if len(meta.Namespace) == 0 {
if len(meta.GetNamespace()) == 0 {
allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), ""))
} else {
for _, msg := range ValidateNamespaceName(meta.Namespace, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), meta.Namespace, msg))
for _, msg := range ValidateNamespaceName(meta.GetNamespace(), false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), meta.GetNamespace(), msg))
}
}
} else {
if len(meta.Namespace) != 0 {
if len(meta.GetNamespace()) != 0 {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("namespace"), "not allowed on this type"))
}
}
if len(meta.ClusterName) != 0 {
for _, msg := range ValidateClusterName(meta.ClusterName, false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("clusterName"), meta.ClusterName, msg))
if len(meta.GetClusterName()) != 0 {
for _, msg := range ValidateClusterName(meta.GetClusterName(), false) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("clusterName"), meta.GetClusterName(), msg))
}
}
allErrs = append(allErrs, ValidateNonnegativeField(meta.Generation, fldPath.Child("generation"))...)
allErrs = append(allErrs, v1validation.ValidateLabels(meta.Labels, fldPath.Child("labels"))...)
allErrs = append(allErrs, ValidateAnnotations(meta.Annotations, fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidateOwnerReferences(meta.OwnerReferences, fldPath.Child("ownerReferences"))...)
allErrs = append(allErrs, ValidateFinalizers(meta.Finalizers, fldPath.Child("finalizers"))...)
allErrs = append(allErrs, ValidateNonnegativeField(meta.GetGeneration(), fldPath.Child("generation"))...)
allErrs = append(allErrs, v1validation.ValidateLabels(meta.GetLabels(), fldPath.Child("labels"))...)
allErrs = append(allErrs, ValidateAnnotations(meta.GetAnnotations(), fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidateOwnerReferences(meta.GetOwnerReferences(), fldPath.Child("ownerReferences"))...)
allErrs = append(allErrs, ValidateFinalizers(meta.GetFinalizers(), fldPath.Child("finalizers"))...)
return allErrs
}

Expand All @@ -197,65 +211,81 @@ func ValidateFinalizers(finalizers []string, fldPath *field.Path) field.ErrorLis

// ValidateObjectMetaUpdate validates an object's metadata when updated
func ValidateObjectMetaUpdate(newMeta, oldMeta *metav1.ObjectMeta, fldPath *field.Path) field.ErrorList {
newMetadata, err := meta.Accessor(newMeta)
if err != nil {
allErrs := field.ErrorList{}
allErrs = append(allErrs, field.Invalid(fldPath, newMeta, err.Error()))
return allErrs
}
oldMetadata, err := meta.Accessor(oldMeta)
if err != nil {
allErrs := field.ErrorList{}
allErrs = append(allErrs, field.Invalid(fldPath, oldMeta, err.Error()))
return allErrs
}
return ValidateObjectMetaAccessorUpdate(newMetadata, oldMetadata, fldPath)
}

func ValidateObjectMetaAccessorUpdate(newMeta, oldMeta metav1.Object, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

if !RepairMalformedUpdates && newMeta.UID != oldMeta.UID {
allErrs = append(allErrs, field.Invalid(fldPath.Child("uid"), newMeta.UID, "field is immutable"))
if !RepairMalformedUpdates && newMeta.GetUID() != oldMeta.GetUID() {
allErrs = append(allErrs, field.Invalid(fldPath.Child("uid"), newMeta.GetUID(), "field is immutable"))
}
// in the event it is left empty, set it, to allow clients more flexibility
// TODO: remove the following code that repairs the update request when we retire the clients that modify the immutable fields.
// Please do not copy this pattern elsewhere; validation functions should not be modifying the objects they are passed!
if RepairMalformedUpdates {
if len(newMeta.UID) == 0 {
newMeta.UID = oldMeta.UID
if len(newMeta.GetUID()) == 0 {
newMeta.SetUID(oldMeta.GetUID())
}
// ignore changes to timestamp
if oldMeta.CreationTimestamp.IsZero() {
oldMeta.CreationTimestamp = newMeta.CreationTimestamp
if oldCreationTime := oldMeta.GetCreationTimestamp(); oldCreationTime.IsZero() {
oldMeta.SetCreationTimestamp(newMeta.GetCreationTimestamp())
} else {
newMeta.CreationTimestamp = oldMeta.CreationTimestamp
newMeta.SetCreationTimestamp(oldMeta.GetCreationTimestamp())
}
// an object can never remove a deletion timestamp or clear/change grace period seconds
if !oldMeta.DeletionTimestamp.IsZero() {
newMeta.DeletionTimestamp = oldMeta.DeletionTimestamp
if !oldMeta.GetDeletionTimestamp().IsZero() {
newMeta.SetDeletionTimestamp(oldMeta.GetDeletionTimestamp())
}
if oldMeta.DeletionGracePeriodSeconds != nil && newMeta.DeletionGracePeriodSeconds == nil {
newMeta.DeletionGracePeriodSeconds = oldMeta.DeletionGracePeriodSeconds
if oldMeta.GetDeletionGracePeriodSeconds() != nil && newMeta.GetDeletionGracePeriodSeconds() == nil {
newMeta.SetDeletionGracePeriodSeconds(oldMeta.GetDeletionGracePeriodSeconds())
}
}

// TODO: needs to check if newMeta==nil && oldMeta !=nil after the repair logic is removed.
if newMeta.DeletionGracePeriodSeconds != nil && (oldMeta.DeletionGracePeriodSeconds == nil || *newMeta.DeletionGracePeriodSeconds != *oldMeta.DeletionGracePeriodSeconds) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("deletionGracePeriodSeconds"), newMeta.DeletionGracePeriodSeconds, "field is immutable; may only be changed via deletion"))
if newMeta.GetDeletionGracePeriodSeconds() != nil && (oldMeta.GetDeletionGracePeriodSeconds() == nil || *newMeta.GetDeletionGracePeriodSeconds() != *oldMeta.GetDeletionGracePeriodSeconds()) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("deletionGracePeriodSeconds"), newMeta.GetDeletionGracePeriodSeconds(), "field is immutable; may only be changed via deletion"))
}
if newMeta.DeletionTimestamp != nil && (oldMeta.DeletionTimestamp == nil || !newMeta.DeletionTimestamp.Equal(*oldMeta.DeletionTimestamp)) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("deletionTimestamp"), newMeta.DeletionTimestamp, "field is immutable; may only be changed via deletion"))
if newMeta.GetDeletionTimestamp() != nil && (oldMeta.GetDeletionTimestamp() == nil || !newMeta.GetDeletionTimestamp().Equal(*oldMeta.GetDeletionTimestamp())) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("deletionTimestamp"), newMeta.GetDeletionTimestamp(), "field is immutable; may only be changed via deletion"))
}

// Finalizers cannot be added if the object is already being deleted.
if oldMeta.DeletionTimestamp != nil {
allErrs = append(allErrs, ValidateNoNewFinalizers(newMeta.Finalizers, oldMeta.Finalizers, fldPath.Child("finalizers"))...)
if oldMeta.GetDeletionTimestamp() != nil {
allErrs = append(allErrs, ValidateNoNewFinalizers(newMeta.GetFinalizers(), oldMeta.GetFinalizers(), fldPath.Child("finalizers"))...)
}

// Reject updates that don't specify a resource version
if len(newMeta.ResourceVersion) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceVersion"), newMeta.ResourceVersion, "must be specified for an update"))
if len(newMeta.GetResourceVersion()) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceVersion"), newMeta.GetResourceVersion(), "must be specified for an update"))
}

// Generation shouldn't be decremented
if newMeta.Generation < oldMeta.Generation {
allErrs = append(allErrs, field.Invalid(fldPath.Child("generation"), newMeta.Generation, "must not be decremented"))
if newMeta.GetGeneration() < oldMeta.GetGeneration() {
allErrs = append(allErrs, field.Invalid(fldPath.Child("generation"), newMeta.GetGeneration(), "must not be decremented"))
}

allErrs = append(allErrs, ValidateImmutableField(newMeta.Name, oldMeta.Name, fldPath.Child("name"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.Namespace, oldMeta.Namespace, fldPath.Child("namespace"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.UID, oldMeta.UID, fldPath.Child("uid"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.CreationTimestamp, oldMeta.CreationTimestamp, fldPath.Child("creationTimestamp"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.ClusterName, oldMeta.ClusterName, fldPath.Child("clusterName"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetName(), oldMeta.GetName(), fldPath.Child("name"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetNamespace(), oldMeta.GetNamespace(), fldPath.Child("namespace"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetUID(), oldMeta.GetUID(), fldPath.Child("uid"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetCreationTimestamp(), oldMeta.GetCreationTimestamp(), fldPath.Child("creationTimestamp"))...)
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetClusterName(), oldMeta.GetClusterName(), fldPath.Child("clusterName"))...)

allErrs = append(allErrs, v1validation.ValidateLabels(newMeta.Labels, fldPath.Child("labels"))...)
allErrs = append(allErrs, ValidateAnnotations(newMeta.Annotations, fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidateOwnerReferences(newMeta.OwnerReferences, fldPath.Child("ownerReferences"))...)
allErrs = append(allErrs, v1validation.ValidateLabels(newMeta.GetLabels(), fldPath.Child("labels"))...)
allErrs = append(allErrs, ValidateAnnotations(newMeta.GetAnnotations(), fldPath.Child("annotations"))...)
allErrs = append(allErrs, ValidateOwnerReferences(newMeta.GetOwnerReferences(), fldPath.Child("ownerReferences"))...)

return allErrs
}
6 changes: 3 additions & 3 deletions staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ func NewUIDPreconditions(uid string) *Preconditions {
}

// HasObjectMetaSystemFieldValues returns true if fields that are managed by the system on ObjectMeta have values.
func HasObjectMetaSystemFieldValues(meta *ObjectMeta) bool {
return !meta.CreationTimestamp.Time.IsZero() ||
len(meta.UID) != 0
func HasObjectMetaSystemFieldValues(meta Object) bool {
return !meta.GetCreationTimestamp().Time.IsZero() ||
len(meta.GetUID()) != 0
}
25 changes: 10 additions & 15 deletions staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,10 @@ limitations under the License.
package v1

import (
"k8s.io/apimachinery/pkg/conversion"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
)

// ObjectMetaFor returns a pointer to a provided object's ObjectMeta.
// TODO: allow runtime.Unknown to extract this object
// TODO: Remove this function and use meta.ObjectMetaAccessor() instead.
func ObjectMetaFor(obj runtime.Object) (*ObjectMeta, error) {
v, err := conversion.EnforcePtr(obj)
if err != nil {
return nil, err
}
var meta *ObjectMeta
err = runtime.FieldPtr(v, "ObjectMeta", &meta)
return meta, err
}

// TODO: move this, Object, List, and Type to a different package
type ObjectMetaAccessor interface {
GetObjectMeta() Object
Expand All @@ -56,12 +41,16 @@ type Object interface {
SetUID(uid types.UID)
GetResourceVersion() string
SetResourceVersion(version string)
GetGeneration() int64
SetGeneration(generation int64)
GetSelfLink() string
SetSelfLink(selfLink string)
GetCreationTimestamp() Time
SetCreationTimestamp(timestamp Time)
GetDeletionTimestamp() *Time
SetDeletionTimestamp(timestamp *Time)
GetDeletionGracePeriodSeconds() *int64
SetDeletionGracePeriodSeconds(*int64)
GetLabels() map[string]string
SetLabels(labels map[string]string)
GetAnnotations() map[string]string
Expand Down Expand Up @@ -132,6 +121,8 @@ func (meta *ObjectMeta) GetUID() types.UID { return meta.UID }
func (meta *ObjectMeta) SetUID(uid types.UID) { meta.UID = uid }
func (meta *ObjectMeta) GetResourceVersion() string { return meta.ResourceVersion }
func (meta *ObjectMeta) SetResourceVersion(version string) { meta.ResourceVersion = version }
func (meta *ObjectMeta) GetGeneration() int64 { return meta.Generation }
func (meta *ObjectMeta) SetGeneration(generation int64) { meta.Generation = generation }
func (meta *ObjectMeta) GetSelfLink() string { return meta.SelfLink }
func (meta *ObjectMeta) SetSelfLink(selfLink string) { meta.SelfLink = selfLink }
func (meta *ObjectMeta) GetCreationTimestamp() Time { return meta.CreationTimestamp }
Expand All @@ -142,6 +133,10 @@ func (meta *ObjectMeta) GetDeletionTimestamp() *Time { return meta.DeletionTimes
func (meta *ObjectMeta) SetDeletionTimestamp(deletionTimestamp *Time) {
meta.DeletionTimestamp = deletionTimestamp
}
func (meta *ObjectMeta) GetDeletionGracePeriodSeconds() *int64 { return meta.DeletionGracePeriodSeconds }
func (meta *ObjectMeta) SetDeletionGracePeriodSeconds(deletionGracePeriodSeconds *int64) {
meta.DeletionGracePeriodSeconds = deletionGracePeriodSeconds
}
func (meta *ObjectMeta) GetLabels() map[string]string { return meta.Labels }
func (meta *ObjectMeta) SetLabels(labels map[string]string) { meta.Labels = labels }
func (meta *ObjectMeta) GetAnnotations() map[string]string { return meta.Annotations }
Expand Down