From 52b582271b5b113b56b9bca39e3fe45cb9355b60 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sun, 26 Oct 2014 22:21:11 -0400 Subject: [PATCH 1/2] Typo in conversion Godoc --- pkg/conversion/scheme.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/conversion/scheme.go b/pkg/conversion/scheme.go index cad4c4ff2db..fbb97aab23a 100644 --- a/pkg/conversion/scheme.go +++ b/pkg/conversion/scheme.go @@ -220,7 +220,7 @@ func (s *Scheme) generateConvertMeta(srcVersion, destVersion string) *Meta { } // DataVersionAndKind will return the APIVersion and Kind of the given wire-format -// enconding of an API Object, or an error. +// encoding of an API Object, or an error. func (s *Scheme) DataVersionAndKind(data []byte) (version, kind string, err error) { return s.MetaFactory.Interpret(data) } From 66ace4c270a5beb0dc9903c333b121e0273d6477 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Sun, 26 Oct 2014 23:01:17 -0400 Subject: [PATCH 2/2] Begin to unify ResourceVersioner and SelfLinker Create a new MetadataAccessor interface that combines both and use it where previously latest.ResourceVersioner and SelfLinker were being used. Adds Namespace to the get/set interface. Adds TODO about future fast path for metadata (as per thockin's comment) --- pkg/api/latest/latest.go | 20 ++-- pkg/api/meta/meta.go | 158 ++++++++++++++++++++++--- pkg/api/meta/meta_test.go | 147 ++++++++++++++++++++++- pkg/api/testapi/testapi.go | 7 +- pkg/master/master.go | 2 +- pkg/registry/event/registry_test.go | 2 +- pkg/registry/generic/etcd/etcd_test.go | 2 +- pkg/runtime/types.go | 1 + pkg/tools/etcd_tools_test.go | 2 +- 9 files changed, 303 insertions(+), 38 deletions(-) diff --git a/pkg/api/latest/latest.go b/pkg/api/latest/latest.go index 4c2bdc5d467..e2aa4987a3e 100644 --- a/pkg/api/latest/latest.go +++ b/pkg/api/latest/latest.go @@ -45,22 +45,24 @@ var Versions = []string{"v1beta1", "v1beta2"} // This codec can decode any object that Kubernetes is aware of. var Codec = v1beta1.Codec +// accessor is the shared static metadata accessor for the API. +var accessor = meta.NewAccessor() + // ResourceVersioner describes a default versioner that can handle all types // of versioning. // TODO: when versioning changes, make this part of each API definition. -var ResourceVersioner = meta.NewResourceVersioner() +var ResourceVersioner runtime.ResourceVersioner = accessor // SelfLinker can set or get the SelfLink field of all API types. // TODO: when versioning changes, make this part of each API definition. // TODO(lavalamp): Combine SelfLinker & ResourceVersioner interfaces, force all uses // to go through the InterfacesFor method below. -var SelfLinker = meta.NewSelfLinker() +var SelfLinker runtime.SelfLinker = accessor // VersionInterfaces contains the interfaces one should use for dealing with types of a particular version. type VersionInterfaces struct { runtime.Codec - runtime.ResourceVersioner - runtime.SelfLinker + meta.MetadataAccessor } // InterfacesFor returns the default Codec and ResourceVersioner for a given version @@ -69,15 +71,13 @@ func InterfacesFor(version string) (*VersionInterfaces, error) { switch version { case "v1beta1": return &VersionInterfaces{ - Codec: v1beta1.Codec, - ResourceVersioner: ResourceVersioner, - SelfLinker: SelfLinker, + Codec: v1beta1.Codec, + MetadataAccessor: accessor, }, nil case "v1beta2": return &VersionInterfaces{ - Codec: v1beta2.Codec, - ResourceVersioner: ResourceVersioner, - SelfLinker: SelfLinker, + Codec: v1beta2.Codec, + MetadataAccessor: accessor, }, nil default: return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(Versions, ", ")) diff --git a/pkg/api/meta/meta.go b/pkg/api/meta/meta.go index 6509fbabfd7..cd850d1a293 100644 --- a/pkg/api/meta/meta.go +++ b/pkg/api/meta/meta.go @@ -24,9 +24,13 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" ) -// Interface lets you work with object metadata from any of the versioned or -// internal API objects. +// Interface lets you work with object and list metadata from any of the versioned or +// internal API objects. Attempting to set or retrieve a field on an object that does +// not support that field (Name, UID, Namespace on lists) will be a no-op and return +// a default value. type Interface interface { + Namespace() string + SetNamespace(namespace string) Name() string SetName(name string) UID() string @@ -45,6 +49,7 @@ type Interface interface { // obj must be a pointer to an API type. An error is returned if the minimum // required fields are missing. Fields that are not required return the default // value and are a no-op if set. +// TODO: add a fast path for *TypeMeta and *ObjectMeta for internal objects func Accessor(obj interface{}) (Interface, error) { v, err := conversion.EnforcePtr(obj) if err != nil { @@ -62,26 +67,26 @@ func Accessor(obj interface{}) (Interface, error) { a := &genericAccessor{} if err := extractFromTypeMeta(typeMeta, a); err != nil { - return nil, fmt.Errorf("unable to find type fields on %#v", typeMeta) + return nil, fmt.Errorf("unable to find type fields on %#v: %v", typeMeta, err) } objectMeta := v.FieldByName("ObjectMeta") if objectMeta.IsValid() { // look for the ObjectMeta fields if err := extractFromObjectMeta(objectMeta, a); err != nil { - return nil, fmt.Errorf("unable to find object fields on %#v", objectMeta) + return nil, fmt.Errorf("unable to find object fields on %#v: %v", objectMeta, err) } } else { listMeta := v.FieldByName("ListMeta") if listMeta.IsValid() { // look for the ListMeta fields if err := extractFromListMeta(listMeta, a); err != nil { - return nil, fmt.Errorf("unable to find list fields on %#v", listMeta) + return nil, fmt.Errorf("unable to find list fields on %#v: %v", listMeta, err) } } else { // look for the older TypeMeta with all metadata if err := extractFromObjectMeta(typeMeta, a); err != nil { - return nil, fmt.Errorf("unable to find object fields on %#v", typeMeta) + return nil, fmt.Errorf("unable to find object fields on %#v: %v", typeMeta, err) } } } @@ -89,33 +94,92 @@ func Accessor(obj interface{}) (Interface, error) { return a, nil } -// NewResourceVersioner returns a ResourceVersioner that can set or -// retrieve ResourceVersion on objects derived from TypeMeta. -func NewResourceVersioner() runtime.ResourceVersioner { +// MetadataAccessor lets you work with object metadata from any of the versioned or +// internal API objects. +type MetadataAccessor interface { + APIVersion(obj runtime.Object) (string, error) + SetAPIVersion(obj runtime.Object, version string) error + + Kind(obj runtime.Object) (string, error) + SetKind(obj runtime.Object, kind string) error + + Namespace(obj runtime.Object) (string, error) + SetNamespace(obj runtime.Object, namespace string) error + + Name(obj runtime.Object) (string, error) + SetName(obj runtime.Object, name string) error + + UID(obj runtime.Object) (string, error) + SetUID(obj runtime.Object, uid string) error + + SelfLink(obj runtime.Object) (string, error) + SetSelfLink(obj runtime.Object, selfLink string) error + + runtime.ResourceVersioner +} + +// NewAccessor returns a MetadataAccessor that can retrieve +// or manipulate resource version on objects derived from core API +// metadata concepts. +func NewAccessor() MetadataAccessor { return resourceAccessor{} } // resourceAccessor implements ResourceVersioner and SelfLinker. type resourceAccessor struct{} -func (v resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) { +func (resourceAccessor) Kind(obj runtime.Object) (string, error) { accessor, err := Accessor(obj) if err != nil { return "", err } - return accessor.ResourceVersion(), nil + return accessor.Kind(), nil } -func (v resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error { +func (resourceAccessor) SetKind(obj runtime.Object, kind string) error { accessor, err := Accessor(obj) if err != nil { return err } - accessor.SetResourceVersion(version) + accessor.SetKind(kind) return nil } -func (v resourceAccessor) Name(obj runtime.Object) (string, error) { +func (resourceAccessor) APIVersion(obj runtime.Object) (string, error) { + accessor, err := Accessor(obj) + if err != nil { + return "", err + } + return accessor.APIVersion(), nil +} + +func (resourceAccessor) SetAPIVersion(obj runtime.Object, version string) error { + accessor, err := Accessor(obj) + if err != nil { + return err + } + accessor.SetAPIVersion(version) + return nil +} + +func (resourceAccessor) Namespace(obj runtime.Object) (string, error) { + accessor, err := Accessor(obj) + if err != nil { + return "", err + } + return accessor.Namespace(), nil +} + +func (resourceAccessor) SetNamespace(obj runtime.Object, namespace string) error { + accessor, err := Accessor(obj) + if err != nil { + return err + } + accessor.SetNamespace(namespace) + return nil +} + +func (resourceAccessor) Name(obj runtime.Object) (string, error) { accessor, err := Accessor(obj) if err != nil { return "", err @@ -123,7 +187,33 @@ func (v resourceAccessor) Name(obj runtime.Object) (string, error) { return accessor.Name(), nil } -func (v resourceAccessor) SelfLink(obj runtime.Object) (string, error) { +func (resourceAccessor) SetName(obj runtime.Object, name string) error { + accessor, err := Accessor(obj) + if err != nil { + return err + } + accessor.SetName(name) + return nil +} + +func (resourceAccessor) UID(obj runtime.Object) (string, error) { + accessor, err := Accessor(obj) + if err != nil { + return "", err + } + return accessor.UID(), nil +} + +func (resourceAccessor) SetUID(obj runtime.Object, uid string) error { + accessor, err := Accessor(obj) + if err != nil { + return err + } + accessor.SetUID(uid) + return nil +} + +func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) { accessor, err := Accessor(obj) if err != nil { return "", err @@ -131,7 +221,7 @@ func (v resourceAccessor) SelfLink(obj runtime.Object) (string, error) { return accessor.SelfLink(), nil } -func (v resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error { +func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error { accessor, err := Accessor(obj) if err != nil { return err @@ -140,14 +230,27 @@ func (v resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error return nil } -// NewSelfLinker returns a SelfLinker that works on all TypeMeta SelfLink fields. -func NewSelfLinker() runtime.SelfLinker { - return resourceAccessor{} +func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) { + accessor, err := Accessor(obj) + if err != nil { + return "", err + } + return accessor.ResourceVersion(), nil +} + +func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error { + accessor, err := Accessor(obj) + if err != nil { + return err + } + accessor.SetResourceVersion(version) + return nil } // genericAccessor contains pointers to strings that can modify an arbitrary // struct and implements the Accessor interface. type genericAccessor struct { + namespace *string name *string uid *string apiVersion *string @@ -156,6 +259,20 @@ type genericAccessor struct { selfLink *string } +func (a genericAccessor) Namespace() string { + if a.namespace == nil { + return "" + } + return *a.namespace +} + +func (a genericAccessor) SetNamespace(namespace string) { + if a.namespace == nil { + return + } + *a.namespace = namespace +} + func (a genericAccessor) Name() string { if a.name == nil { return "" @@ -254,6 +371,9 @@ func extractFromTypeMeta(v reflect.Value, a *genericAccessor) error { // extractFromObjectMeta extracts pointers to metadata fields from an object func extractFromObjectMeta(v reflect.Value, a *genericAccessor) error { + if err := fieldPtr(v, "Namespace", &a.namespace); err != nil { + return err + } if err := fieldPtr(v, "Name", &a.name); err != nil { return err } diff --git a/pkg/api/meta/meta_test.go b/pkg/api/meta/meta_test.go index 1d7653e16fe..d6e9f04bfec 100644 --- a/pkg/api/meta/meta_test.go +++ b/pkg/api/meta/meta_test.go @@ -26,6 +26,7 @@ import ( func TestGenericTypeMeta(t *testing.T) { type TypeMeta struct { Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` Name string `json:"name,omitempty" yaml:"name,omitempty"` UID string `json:"uid,omitempty" yaml:"uid,omitempty"` CreationTimestamp util.Time `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"` @@ -38,6 +39,7 @@ func TestGenericTypeMeta(t *testing.T) { } j := Object{ TypeMeta{ + Namespace: "bar", Name: "foo", UID: "uid", APIVersion: "a", @@ -50,6 +52,9 @@ func TestGenericTypeMeta(t *testing.T) { if err != nil { t.Fatalf("new err: %v", err) } + if e, a := "bar", accessor.Namespace(); e != a { + t.Errorf("expected %v, got %v", e, a) + } if e, a := "foo", accessor.Name(); e != a { t.Errorf("expected %v, got %v", e, a) } @@ -69,6 +74,7 @@ func TestGenericTypeMeta(t *testing.T) { t.Errorf("expected %v, got %v", e, a) } + accessor.SetNamespace("baz") accessor.SetName("bar") accessor.SetUID("other") accessor.SetAPIVersion("c") @@ -77,6 +83,9 @@ func TestGenericTypeMeta(t *testing.T) { accessor.SetSelfLink("google.com") // Prove that accessor changes the original object. + if e, a := "baz", j.Namespace; e != a { + t.Errorf("expected %v, got %v", e, a) + } if e, a := "bar", j.Name; e != a { t.Errorf("expected %v, got %v", e, a) } @@ -97,12 +106,138 @@ func TestGenericTypeMeta(t *testing.T) { } } +type InternalTypeMeta struct { + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` + UID string `json:"uid,omitempty" yaml:"uid,omitempty"` + CreationTimestamp util.Time `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"` + SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"` + ResourceVersion string `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"` + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` +} +type InternalObject struct { + TypeMeta InternalTypeMeta `json:",inline" yaml:",inline"` +} + +func (*InternalObject) IsAnAPIObject() {} + +func TestGenericTypeMetaAccessor(t *testing.T) { + j := &InternalObject{ + InternalTypeMeta{ + Namespace: "bar", + Name: "foo", + UID: "uid", + APIVersion: "a", + Kind: "b", + ResourceVersion: "1", + SelfLink: "some/place/only/we/know", + }, + } + accessor := NewAccessor() + namespace, err := accessor.Namespace(j) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if e, a := "bar", namespace; e != a { + t.Errorf("expected %v, got %v", e, a) + } + name, err := accessor.Name(j) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if e, a := "foo", name; e != a { + t.Errorf("expected %v, got %v", e, a) + } + uid, err := accessor.UID(j) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if e, a := "uid", uid; e != a { + t.Errorf("expected %v, got %v", e, a) + } + apiVersion, err := accessor.APIVersion(j) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if e, a := "a", apiVersion; e != a { + t.Errorf("expected %v, got %v", e, a) + } + kind, err := accessor.Kind(j) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if e, a := "b", kind; e != a { + t.Errorf("expected %v, got %v", e, a) + } + rv, err := accessor.ResourceVersion(j) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if e, a := "1", rv; e != a { + t.Errorf("expected %v, got %v", e, a) + } + selfLink, err := accessor.SelfLink(j) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if e, a := "some/place/only/we/know", selfLink; e != a { + t.Errorf("expected %v, got %v", e, a) + } + + if err := accessor.SetNamespace(j, "baz"); err != nil { + t.Errorf("unexpected error: %v", err) + } + if err := accessor.SetName(j, "bar"); err != nil { + t.Errorf("unexpected error: %v", err) + } + if err := accessor.SetUID(j, "other"); err != nil { + t.Errorf("unexpected error: %v", err) + } + if err := accessor.SetAPIVersion(j, "c"); err != nil { + t.Errorf("unexpected error: %v", err) + } + if err := accessor.SetKind(j, "d"); err != nil { + t.Errorf("unexpected error: %v", err) + } + if err := accessor.SetResourceVersion(j, "2"); err != nil { + t.Errorf("unexpected error: %v", err) + } + if err := accessor.SetSelfLink(j, "google.com"); err != nil { + t.Errorf("unexpected error: %v", err) + } + + // Prove that accessor changes the original object. + if e, a := "baz", j.TypeMeta.Namespace; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "bar", j.TypeMeta.Name; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "other", j.TypeMeta.UID; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "c", j.TypeMeta.APIVersion; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "d", j.TypeMeta.Kind; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "2", j.TypeMeta.ResourceVersion; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "google.com", j.TypeMeta.SelfLink; e != a { + t.Errorf("expected %v, got %v", e, a) + } +} + func TestGenericObjectMeta(t *testing.T) { type TypeMeta struct { Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` } type ObjectMeta struct { + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` Name string `json:"name,omitempty" yaml:"name,omitempty"` UID string `json:"uid,omitempty" yaml:"uid,omitempty"` CreationTimestamp util.Time `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"` @@ -119,6 +254,7 @@ func TestGenericObjectMeta(t *testing.T) { Kind: "b", }, ObjectMeta{ + Namespace: "bar", Name: "foo", UID: "uid", ResourceVersion: "1", @@ -129,6 +265,9 @@ func TestGenericObjectMeta(t *testing.T) { if err != nil { t.Fatalf("new err: %v", err) } + if e, a := "bar", accessor.Namespace(); e != a { + t.Errorf("expected %v, got %v", e, a) + } if e, a := "foo", accessor.Name(); e != a { t.Errorf("expected %v, got %v", e, a) } @@ -148,6 +287,7 @@ func TestGenericObjectMeta(t *testing.T) { t.Errorf("expected %v, got %v", e, a) } + accessor.SetNamespace("baz") accessor.SetName("bar") accessor.SetUID("other") accessor.SetAPIVersion("c") @@ -156,6 +296,9 @@ func TestGenericObjectMeta(t *testing.T) { accessor.SetSelfLink("google.com") // Prove that accessor changes the original object. + if e, a := "baz", j.Namespace; e != a { + t.Errorf("expected %v, got %v", e, a) + } if e, a := "bar", j.Name; e != a { t.Errorf("expected %v, got %v", e, a) } @@ -265,7 +408,7 @@ func TestResourceVersionerOfAPI(t *testing.T) { "api object with version": {&MyAPIObject{TypeMeta: runtime.TypeMeta{ResourceVersion: "1"}}, "1"}, "pointer to api object with version": {&MyAPIObject{TypeMeta: runtime.TypeMeta{ResourceVersion: "1"}}, "1"}, } - versioning := NewResourceVersioner() + versioning := NewAccessor() for key, testCase := range testCases { actual, err := versioning.ResourceVersion(testCase.Object) if err != nil { @@ -328,7 +471,7 @@ func TestTypeMetaSelfLinker(t *testing.T) { }, } - linker := NewSelfLinker() + var linker runtime.SelfLinker = NewAccessor() for name, item := range table { got, err := linker.SelfLink(item.obj) if e, a := item.succeed, err == nil; e != a { diff --git a/pkg/api/testapi/testapi.go b/pkg/api/testapi/testapi.go index f9ef1816176..b75604222c5 100644 --- a/pkg/api/testapi/testapi.go +++ b/pkg/api/testapi/testapi.go @@ -22,6 +22,7 @@ import ( "os" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" ) @@ -44,14 +45,14 @@ func Codec() runtime.Codec { return interfaces.Codec } -// ResourceVersioner returns the ResourceVersioner for the API version to test against, +// MetadataAccessor returns the MetadataAccessor for the API version to test against, // as set by the KUBE_API_VERSION env var. -func ResourceVersioner() runtime.ResourceVersioner { +func MetadataAccessor() meta.MetadataAccessor { interfaces, err := latest.InterfacesFor(Version()) if err != nil { panic(err) } - return interfaces.ResourceVersioner + return interfaces.MetadataAccessor } // SelfLink returns a self link that will appear to be for the version Version(). diff --git a/pkg/master/master.go b/pkg/master/master.go index 0db5ca52ba7..62c4e4ebd59 100644 --- a/pkg/master/master.go +++ b/pkg/master/master.go @@ -81,7 +81,7 @@ func NewEtcdHelper(client tools.EtcdGetSet, version string) (helper tools.EtcdHe if err != nil { return helper, err } - return tools.EtcdHelper{client, versionInterfaces.Codec, tools.RuntimeVersionAdapter{versionInterfaces.ResourceVersioner}}, nil + return tools.EtcdHelper{client, versionInterfaces.Codec, tools.RuntimeVersionAdapter{versionInterfaces.MetadataAccessor}}, nil } // New returns a new instance of Master connected to the given etcd server. diff --git a/pkg/registry/event/registry_test.go b/pkg/registry/event/registry_test.go index f9ce4dc6484..ad9aa2d2231 100644 --- a/pkg/registry/event/registry_test.go +++ b/pkg/registry/event/registry_test.go @@ -36,7 +36,7 @@ var testTTL uint64 = 60 func NewTestEventEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, generic.Registry) { f := tools.NewFakeEtcdClient(t) f.TestIndex = true - h := tools.EtcdHelper{f, testapi.Codec(), tools.RuntimeVersionAdapter{testapi.ResourceVersioner()}} + h := tools.EtcdHelper{f, testapi.Codec(), tools.RuntimeVersionAdapter{testapi.MetadataAccessor()}} return f, NewEtcdRegistry(h, testTTL) } diff --git a/pkg/registry/generic/etcd/etcd_test.go b/pkg/registry/generic/etcd/etcd_test.go index b1aac523025..6f1ed30ed2f 100644 --- a/pkg/registry/generic/etcd/etcd_test.go +++ b/pkg/registry/generic/etcd/etcd_test.go @@ -36,7 +36,7 @@ import ( func NewTestGenericEtcdRegistry(t *testing.T) (*tools.FakeEtcdClient, *Etcd) { f := tools.NewFakeEtcdClient(t) f.TestIndex = true - h := tools.EtcdHelper{f, testapi.Codec(), tools.RuntimeVersionAdapter{testapi.ResourceVersioner()}} + h := tools.EtcdHelper{f, testapi.Codec(), tools.RuntimeVersionAdapter{testapi.MetadataAccessor()}} return f, &Etcd{ NewFunc: func() runtime.Object { return &api.Pod{} }, NewListFunc: func() runtime.Object { return &api.PodList{} }, diff --git a/pkg/runtime/types.go b/pkg/runtime/types.go index c20c6a9df74..f79ec42f4d2 100644 --- a/pkg/runtime/types.go +++ b/pkg/runtime/types.go @@ -38,6 +38,7 @@ type TypeMeta struct { APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"` Name string `json:"name,omitempty" yaml:"name,omitempty"` UID string `json:"uid,omitempty" yaml:"uid,omitempty"` CreationTimestamp util.Time `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"` diff --git a/pkg/tools/etcd_tools_test.go b/pkg/tools/etcd_tools_test.go index 9cbe4646e35..532c07c06a0 100644 --- a/pkg/tools/etcd_tools_test.go +++ b/pkg/tools/etcd_tools_test.go @@ -46,7 +46,7 @@ func (*TestResource) IsAnAPIObject() {} var scheme *runtime.Scheme var codec runtime.Codec -var versioner = RuntimeVersionAdapter{meta.NewResourceVersioner()} +var versioner = RuntimeVersionAdapter{meta.NewAccessor()} func init() { scheme = runtime.NewScheme()