Set uid during object create

This commit is contained in:
derekwaynecarr 2014-11-12 16:27:10 -05:00
parent d4108ec47e
commit 15701ff403
13 changed files with 106 additions and 11 deletions

33
pkg/api/meta.go Normal file
View File

@ -0,0 +1,33 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta.
func FillObjectMetaSystemFields(ctx Context, meta *ObjectMeta) {
meta.CreationTimestamp = util.Now()
meta.UID = util.NewUUID().String()
}
// 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
}

48
pkg/api/meta_test.go Normal file
View File

@ -0,0 +1,48 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api_test
import (
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
)
// 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")
}
}

View File

@ -68,7 +68,7 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
return nil, errors.NewInvalid("replicationController", controller.Name, errs)
}
controller.CreationTimestamp = util.Now()
api.FillObjectMetaSystemFields(ctx, &controller.ObjectMeta)
return apiserver.MakeAsync(func() (runtime.Object, error) {
err := rs.registry.CreateController(ctx, controller)

View File

@ -264,6 +264,9 @@ func TestCreateController(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !api.HasObjectMetaSystemFieldValues(&controller.ObjectMeta) {
t.Errorf("storage did not populate object meta field values")
}
select {
case <-channel:

View File

@ -24,7 +24,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
@ -68,7 +67,9 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
if len(endpoints.Name) == 0 {
return nil, fmt.Errorf("id is required: %#v", obj)
}
endpoints.CreationTimestamp = util.Now()
api.FillObjectMetaSystemFields(ctx, &endpoints.ObjectMeta)
return apiserver.MakeAsync(func() (runtime.Object, error) {
err := rs.registry.UpdateEndpoints(ctx, endpoints)
if err != nil {

View File

@ -24,7 +24,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
@ -46,7 +45,8 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
if !ok {
return nil, fmt.Errorf("invalid object type")
}
event.CreationTimestamp = util.Now()
api.FillObjectMetaSystemFields(ctx, &event.ObjectMeta)
return apiserver.MakeAsync(func() (runtime.Object, error) {
err := rs.registry.Create(ctx, event.Name, event)

View File

@ -48,6 +48,9 @@ func TestRESTCreate(t *testing.T) {
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
if !api.HasObjectMetaSystemFieldValues(&eventA.ObjectMeta) {
t.Errorf("storage did not populate object meta field values")
}
if e, a := eventA, (<-c).Object; !reflect.DeepEqual(e, a) {
t.Errorf("diff: %s", util.ObjectDiff(e, a))
}

View File

@ -29,7 +29,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
// REST implements the RESTStorage interface, backed by a MinionRegistry.
@ -57,7 +56,7 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
return nil, kerrors.NewInvalid("minion", minion.Name, errs)
}
minion.CreationTimestamp = util.Now()
api.FillObjectMetaSystemFields(ctx, &minion.ObjectMeta)
return apiserver.MakeAsync(func() (runtime.Object, error) {
err := rs.registry.CreateMinion(ctx, minion)

View File

@ -43,6 +43,9 @@ func TestMinionREST(t *testing.T) {
t.Errorf("insert failed")
}
obj := <-c
if !api.HasObjectMetaSystemFieldValues(&obj.Object.(*api.Minion).ObjectMeta) {
t.Errorf("storage did not populate object meta field values")
}
if m, ok := obj.Object.(*api.Minion); !ok || m.Name != "baz" {
t.Errorf("insert return value was weird: %#v", obj)
}

View File

@ -100,7 +100,8 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
if errs := validation.ValidatePod(pod); len(errs) > 0 {
return nil, errors.NewInvalid("pod", pod.Name, errs)
}
pod.CreationTimestamp = util.Now()
api.FillObjectMetaSystemFields(ctx, &pod.ObjectMeta)
return apiserver.MakeAsync(func() (runtime.Object, error) {
if err := rs.registry.CreatePod(ctx, pod); err != nil {

View File

@ -586,13 +586,15 @@ func TestCreatePod(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
select {
case <-channel:
// Do nothing, this is expected.
case <-time.After(time.Millisecond * 100):
t.Error("Unexpected timeout on async channel")
}
if !api.HasObjectMetaSystemFieldValues(&podRegistry.Pod.ObjectMeta) {
t.Errorf("Expected ObjectMeta field values were populated")
}
}
type FakePodInfoGetter struct {

View File

@ -31,7 +31,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/golang/glog"
)
@ -92,7 +91,7 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
return nil, errors.NewInvalid("service", service.Name, errs)
}
service.CreationTimestamp = util.Now()
api.FillObjectMetaSystemFields(ctx, &service.ObjectMeta)
if service.Spec.PortalIP == "" {
// Allocate next available.

View File

@ -55,6 +55,9 @@ func TestServiceRegistryCreate(t *testing.T) {
c, _ := storage.Create(ctx, svc)
created_svc := <-c
created_service := created_svc.Object.(*api.Service)
if !api.HasObjectMetaSystemFieldValues(&created_service.ObjectMeta) {
t.Errorf("storage did not populate object meta field values")
}
if created_service.Name != "foo" {
t.Errorf("Expected foo, but got %v", created_service.Name)
}