Allow handlers earlier in a request flow to inject a UID for an object

This commit is contained in:
derekwaynecarr 2016-05-07 09:23:15 -04:00
parent 5e16101aab
commit 029acfc8aa
3 changed files with 37 additions and 5 deletions

View File

@ -22,6 +22,7 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
"k8s.io/kubernetes/pkg/auth/user" "k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/types"
) )
// Context carries values across API boundaries. // Context carries values across API boundaries.
@ -49,11 +50,16 @@ type Context interface {
// The key type is unexported to prevent collisions // The key type is unexported to prevent collisions
type key int type key int
// namespaceKey is the context key for the request namespace. const (
const namespaceKey key = 0 // namespaceKey is the context key for the request namespace.
namespaceKey key = iota
// userKey is the context key for the request user. // userKey is the context key for the request user.
const userKey key = 1 userKey
// uidKey is the context key for the uid to assign to an object on create.
uidKey
)
// NewContext instantiates a base context object for request flows. // NewContext instantiates a base context object for request flows.
func NewContext() Context { func NewContext() Context {
@ -119,3 +125,14 @@ func UserFrom(ctx Context) (user.Info, bool) {
user, ok := ctx.Value(userKey).(user.Info) user, ok := ctx.Value(userKey).(user.Info)
return user, ok return user, ok
} }
// WithUID returns a copy of parent in which the uid value is set
func WithUID(parent Context, uid types.UID) Context {
return WithValue(parent, uidKey, uid)
}
// UIDFrom returns the value of the uid key on the ctx
func UIDFrom(ctx Context) (types.UID, bool) {
uid, ok := ctx.Value(uidKey).(types.UID)
return uid, ok
}

View File

@ -29,7 +29,13 @@ import (
// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta. // FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta.
func FillObjectMetaSystemFields(ctx Context, meta *ObjectMeta) { func FillObjectMetaSystemFields(ctx Context, meta *ObjectMeta) {
meta.CreationTimestamp = unversioned.Now() meta.CreationTimestamp = unversioned.Now()
meta.UID = util.NewUUID() // allows admission controllers to assign a UID earlier in the request processing
// to support tracking resources pending creation.
uid, found := UIDFrom(ctx)
if !found {
uid = util.NewUUID()
}
meta.UID = uid
meta.SelfLink = "" meta.SelfLink = ""
} }

View File

@ -28,6 +28,7 @@ import (
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util"
) )
var _ meta.Object = &api.ObjectMeta{} var _ meta.Object = &api.ObjectMeta{}
@ -42,6 +43,14 @@ func TestFillObjectMetaSystemFields(t *testing.T) {
} else if len(resource.UID) == 0 { } else if len(resource.UID) == 0 {
t.Errorf("resource.UID missing") t.Errorf("resource.UID missing")
} }
// verify we can inject a UID
uid := util.NewUUID()
ctx = api.WithUID(ctx, uid)
resource = api.ObjectMeta{}
api.FillObjectMetaSystemFields(ctx, &resource)
if resource.UID != uid {
t.Errorf("resource.UID expected: %v, actual: %v", uid, resource.UID)
}
} }
// TestHasObjectMetaSystemFieldValues validates that true is returned if and only if all fields are populated // TestHasObjectMetaSystemFieldValues validates that true is returned if and only if all fields are populated