diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index 8a1e14bfe7c..8eca102533d 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -219,7 +219,10 @@ func ValidateObjectMetaUpdate(old, meta *api.ObjectMeta) errs.ValidationErrorLis if len(meta.UID) == 0 { meta.UID = old.UID } - if meta.CreationTimestamp.IsZero() { + // ignore changes to timestamp + if old.CreationTimestamp.IsZero() { + old.CreationTimestamp = meta.CreationTimestamp + } else { meta.CreationTimestamp = old.CreationTimestamp } diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index f2203ff799a..331446d9fa5 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -19,6 +19,7 @@ package validation import ( "strings" "testing" + "time" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" @@ -53,6 +54,27 @@ func TestValidateObjectMetaCustomName(t *testing.T) { } } +func TestValidateObjectMetaUpdateIgnoresCreationTimestamp(t *testing.T) { + if errs := ValidateObjectMetaUpdate( + &api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(10, 0))}, + &api.ObjectMeta{Name: "test"}, + ); len(errs) != 0 { + t.Fatalf("unexpected errors: %v", errs) + } + if errs := ValidateObjectMetaUpdate( + &api.ObjectMeta{Name: "test"}, + &api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(10, 0))}, + ); len(errs) != 0 { + t.Fatalf("unexpected errors: %v", errs) + } + if errs := ValidateObjectMetaUpdate( + &api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(11, 0))}, + &api.ObjectMeta{Name: "test", CreationTimestamp: util.NewTime(time.Unix(10, 0))}, + ); len(errs) != 0 { + t.Fatalf("unexpected errors: %v", errs) + } +} + // Ensure trailing slash is allowed in generate name func TestValidateObjectMetaTrimsTrailingSlash(t *testing.T) { errs := ValidateObjectMeta(&api.ObjectMeta{Name: "test", GenerateName: "foo-"}, false, nameIsDNSSubdomain)