From 64d98cba7314639bd5dd39e08122d83ab61177a8 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Wed, 22 Oct 2014 22:28:06 -0400 Subject: [PATCH 1/5] Move typemeta.go to api/meta/meta.go Prepares for the meta object to front multiple underlying types when TypeMeta and ObjectMeta is split in internal and v1beta3, but combined in v1beta1 and v1beta2 --- cmd/kubecfg/kubecfg.go | 5 +++-- pkg/api/latest/latest.go | 5 +++-- pkg/api/meta/doc.go | 19 +++++++++++++++++ pkg/{runtime/typemeta.go => api/meta/meta.go} | 21 ++++++++++--------- .../meta/meta_test.go} | 21 ++++++++++--------- pkg/api/ref.go | 3 ++- pkg/api/serialization_test.go | 16 +++----------- pkg/client/cache/reflector.go | 7 ++++--- pkg/kubectl/modify.go | 7 ++++--- pkg/runtime/embedded_test.go | 4 ++++ pkg/runtime/types.go | 9 ++++---- pkg/tools/etcd_tools_test.go | 3 ++- 12 files changed, 71 insertions(+), 49 deletions(-) create mode 100644 pkg/api/meta/doc.go rename pkg/{runtime/typemeta.go => api/meta/meta.go} (87%) rename pkg/{runtime/typemeta_test.go => api/meta/meta_test.go} (92%) diff --git a/cmd/kubecfg/kubecfg.go b/cmd/kubecfg/kubecfg.go index 9708946dec1..c6c74546da5 100644 --- a/cmd/kubecfg/kubecfg.go +++ b/cmd/kubecfg/kubecfg.go @@ -31,6 +31,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubecfg" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" @@ -372,7 +373,7 @@ func executeAPIRequest(ctx api.Context, method string, c *client.Client) bool { if err != nil { glog.Fatalf("error obtaining resource version for update: %v", err) } - jsonBase, err := runtime.FindTypeMeta(obj) + jsonBase, err := meta.FindTypeMeta(obj) if err != nil { glog.Fatalf("error finding json base for update: %v", err) } @@ -408,7 +409,7 @@ func executeAPIRequest(ctx api.Context, method string, c *client.Client) bool { if err != nil { glog.Fatalf("error setting resource version: %v", err) } - jsonBase, err := runtime.FindTypeMeta(obj) + jsonBase, err := meta.FindTypeMeta(obj) if err != nil { glog.Fatalf("error setting resource version: %v", err) } diff --git a/pkg/api/latest/latest.go b/pkg/api/latest/latest.go index 5dec503baf8..531a0067668 100644 --- a/pkg/api/latest/latest.go +++ b/pkg/api/latest/latest.go @@ -20,6 +20,7 @@ import ( "fmt" "strings" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" @@ -47,13 +48,13 @@ var Codec = v1beta1.Codec // 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 = runtime.NewTypeMetaResourceVersioner() +var ResourceVersioner = meta.NewTypeMetaResourceVersioner() // 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 = runtime.NewTypeMetaSelfLinker() +var SelfLinker = meta.NewTypeMetaSelfLinker() // VersionInterfaces contains the interfaces one should use for dealing with types of a particular version. type VersionInterfaces struct { diff --git a/pkg/api/meta/doc.go b/pkg/api/meta/doc.go new file mode 100644 index 00000000000..a388f1d7ec5 --- /dev/null +++ b/pkg/api/meta/doc.go @@ -0,0 +1,19 @@ +/* +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 meta provides functions for retrieving API metadata from objects +// belonging to the Kubernetes API +package meta diff --git a/pkg/runtime/typemeta.go b/pkg/api/meta/meta.go similarity index 87% rename from pkg/runtime/typemeta.go rename to pkg/api/meta/meta.go index 6dc616bd6fc..6ce01543d17 100644 --- a/pkg/runtime/typemeta.go +++ b/pkg/api/meta/meta.go @@ -14,18 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -package runtime +package meta import ( "fmt" "reflect" "github.com/GoogleCloudPlatform/kubernetes/pkg/conversion" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" ) // FindTypeMeta takes an arbitary api type, returns pointer to its TypeMeta field. // obj must be a pointer to an api type. -func FindTypeMeta(obj Object) (TypeMetaInterface, error) { +func FindTypeMeta(obj runtime.Object) (TypeMetaInterface, error) { v, err := conversion.EnforcePtr(obj) if err != nil { return nil, err @@ -48,14 +49,14 @@ func FindTypeMeta(obj Object) (TypeMetaInterface, error) { // NewTypeMetaResourceVersioner returns a ResourceVersioner that can set or // retrieve ResourceVersion on objects derived from TypeMeta. -func NewTypeMetaResourceVersioner() ResourceVersioner { +func NewTypeMetaResourceVersioner() runtime.ResourceVersioner { return jsonBaseModifier{} } // jsonBaseModifier implements ResourceVersioner and SelfLinker. type jsonBaseModifier struct{} -func (v jsonBaseModifier) ResourceVersion(obj Object) (string, error) { +func (v jsonBaseModifier) ResourceVersion(obj runtime.Object) (string, error) { json, err := FindTypeMeta(obj) if err != nil { return "", err @@ -63,7 +64,7 @@ func (v jsonBaseModifier) ResourceVersion(obj Object) (string, error) { return json.ResourceVersion(), nil } -func (v jsonBaseModifier) SetResourceVersion(obj Object, version string) error { +func (v jsonBaseModifier) SetResourceVersion(obj runtime.Object, version string) error { json, err := FindTypeMeta(obj) if err != nil { return err @@ -72,7 +73,7 @@ func (v jsonBaseModifier) SetResourceVersion(obj Object, version string) error { return nil } -func (v jsonBaseModifier) ID(obj Object) (string, error) { +func (v jsonBaseModifier) ID(obj runtime.Object) (string, error) { json, err := FindTypeMeta(obj) if err != nil { return "", err @@ -80,7 +81,7 @@ func (v jsonBaseModifier) ID(obj Object) (string, error) { return json.ID(), nil } -func (v jsonBaseModifier) SelfLink(obj Object) (string, error) { +func (v jsonBaseModifier) SelfLink(obj runtime.Object) (string, error) { json, err := FindTypeMeta(obj) if err != nil { return "", err @@ -88,7 +89,7 @@ func (v jsonBaseModifier) SelfLink(obj Object) (string, error) { return json.SelfLink(), nil } -func (v jsonBaseModifier) SetSelfLink(obj Object, selfLink string) error { +func (v jsonBaseModifier) SetSelfLink(obj runtime.Object, selfLink string) error { json, err := FindTypeMeta(obj) if err != nil { return err @@ -98,12 +99,12 @@ func (v jsonBaseModifier) SetSelfLink(obj Object, selfLink string) error { } // NewTypeMetaSelfLinker returns a SelfLinker that works on all TypeMeta SelfLink fields. -func NewTypeMetaSelfLinker() SelfLinker { +func NewTypeMetaSelfLinker() runtime.SelfLinker { return jsonBaseModifier{} } // TypeMetaInterface lets you work with a TypeMeta from any of the versioned or -// internal APIObjects. +// internal APIruntime.Objects. type TypeMetaInterface interface { ID() string SetID(ID string) diff --git a/pkg/runtime/typemeta_test.go b/pkg/api/meta/meta_test.go similarity index 92% rename from pkg/runtime/typemeta_test.go rename to pkg/api/meta/meta_test.go index bd4375048d5..156d19e3c44 100644 --- a/pkg/runtime/typemeta_test.go +++ b/pkg/api/meta/meta_test.go @@ -14,12 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -package runtime +package meta import ( "reflect" "testing" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) @@ -86,7 +87,7 @@ func TestGenericTypeMeta(t *testing.T) { } type MyAPIObject struct { - TypeMeta `yaml:",inline" json:",inline"` + runtime.TypeMeta `yaml:",inline" json:",inline"` } func (*MyAPIObject) IsAnAPIObject() {} @@ -98,13 +99,13 @@ func (*MyIncorrectlyMarkedAsAPIObject) IsAnAPIObject() {} func TestResourceVersionerOfAPI(t *testing.T) { type T struct { - Object + runtime.Object Expected string } testCases := map[string]T{ "empty api object": {&MyAPIObject{}, ""}, - "api object with version": {&MyAPIObject{TypeMeta: TypeMeta{ResourceVersion: "1"}}, "1"}, - "pointer to api object with version": {&MyAPIObject{TypeMeta: TypeMeta{ResourceVersion: "1"}}, "1"}, + "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 := NewTypeMetaResourceVersioner() for key, testCase := range testCases { @@ -118,7 +119,7 @@ func TestResourceVersionerOfAPI(t *testing.T) { } failingCases := map[string]struct { - Object + runtime.Object Expected string }{ "not a valid object to try": {&MyIncorrectlyMarkedAsAPIObject{}, "1"}, @@ -131,10 +132,10 @@ func TestResourceVersionerOfAPI(t *testing.T) { } setCases := map[string]struct { - Object + runtime.Object Expected string }{ - "pointer to api object with version": {&MyAPIObject{TypeMeta: TypeMeta{ResourceVersion: "1"}}, "1"}, + "pointer to api object with version": {&MyAPIObject{TypeMeta: runtime.TypeMeta{ResourceVersion: "1"}}, "1"}, } for key, testCase := range setCases { if err := versioning.SetResourceVersion(testCase.Object, "5"); err != nil { @@ -152,13 +153,13 @@ func TestResourceVersionerOfAPI(t *testing.T) { func TestTypeMetaSelfLinker(t *testing.T) { table := map[string]struct { - obj Object + obj runtime.Object expect string try string succeed bool }{ "normal": { - obj: &MyAPIObject{TypeMeta: TypeMeta{SelfLink: "foobar"}}, + obj: &MyAPIObject{TypeMeta: runtime.TypeMeta{SelfLink: "foobar"}}, expect: "foobar", try: "newbar", succeed: true, diff --git a/pkg/api/ref.go b/pkg/api/ref.go index fc6fd51fc52..b8ad6153f6e 100644 --- a/pkg/api/ref.go +++ b/pkg/api/ref.go @@ -21,6 +21,7 @@ import ( "fmt" "regexp" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" ) @@ -35,7 +36,7 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) { if obj == nil { return nil, ErrNilObject } - jsonBase, err := runtime.FindTypeMeta(obj) + jsonBase, err := meta.FindTypeMeta(obj) if err != nil { return nil, err } diff --git a/pkg/api/serialization_test.go b/pkg/api/serialization_test.go index e5c9c2371e7..fa3f9e51587 100644 --- a/pkg/api/serialization_test.go +++ b/pkg/api/serialization_test.go @@ -26,6 +26,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" @@ -46,17 +47,6 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs( // APIVersion and Kind must remain blank in memory. j.APIVersion = "" j.Kind = "" - j.Name = c.RandString() - // TODO: Fix JSON/YAML packages and/or write custom encoding - // for uint64's. Somehow the LS *byte* of this is lost, but - // only when all 8 bytes are set. - j.ResourceVersion = strconv.FormatUint(c.RandUint64()>>8, 10) - j.SelfLink = c.RandString() - - var sec, nsec int64 - c.Fuzz(&sec) - c.Fuzz(&nsec) - j.CreationTimestamp = util.Unix(sec, nsec).Rfc3339Copy() }, func(j *api.TypeMeta, c fuzz.Continue) { // We have to customize the randomization of TypeMetas because their @@ -111,7 +101,7 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs( func runTest(t *testing.T, codec runtime.Codec, source runtime.Object) { name := reflect.TypeOf(source).Elem().Name() apiObjectFuzzer.Fuzz(source) - j, err := runtime.FindTypeMeta(source) + j, err := meta.FindTypeMeta(source) if err != nil { t.Fatalf("Unexpected error %v for %#v", err, source) } @@ -170,7 +160,7 @@ func TestTypes(t *testing.T) { t.Errorf("Couldn't make a %v? %v", kind, err) continue } - if _, err := runtime.FindTypeMeta(item); err != nil { + if _, err := meta.FindTypeMeta(item); err != nil { t.Logf("%s is not a TypeMeta and cannot be round tripped: %v", kind, err) continue } diff --git a/pkg/client/cache/reflector.go b/pkg/client/cache/reflector.go index 20298657260..243d56db864 100644 --- a/pkg/client/cache/reflector.go +++ b/pkg/client/cache/reflector.go @@ -23,6 +23,7 @@ import ( "time" apierrs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" @@ -78,7 +79,7 @@ func (r *Reflector) listAndWatch() { glog.Errorf("Failed to list %v: %v", r.expectedType, err) return } - jsonBase, err := runtime.FindTypeMeta(list) + jsonBase, err := meta.FindTypeMeta(list) if err != nil { glog.Errorf("Unable to understand list result %#v", list) return @@ -112,7 +113,7 @@ func (r *Reflector) listAndWatch() { func (r *Reflector) syncWith(items []runtime.Object) error { found := map[string]interface{}{} for _, item := range items { - jsonBase, err := runtime.FindTypeMeta(item) + jsonBase, err := meta.FindTypeMeta(item) if err != nil { return fmt.Errorf("unexpected item in list: %v", err) } @@ -139,7 +140,7 @@ func (r *Reflector) watchHandler(w watch.Interface, resourceVersion *string) err glog.Errorf("expected type %v, but watch event object had type %v", e, a) continue } - jsonBase, err := runtime.FindTypeMeta(event.Object) + jsonBase, err := meta.FindTypeMeta(event.Object) if err != nil { glog.Errorf("unable to understand watch event %#v", event) continue diff --git a/pkg/kubectl/modify.go b/pkg/kubectl/modify.go index 3c06734d9f7..c0dfe277446 100644 --- a/pkg/kubectl/modify.go +++ b/pkg/kubectl/modify.go @@ -20,6 +20,7 @@ import ( "fmt" "io" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" ) @@ -109,7 +110,7 @@ func doUpdate(c *client.RESTClient, resource string, obj runtime.Object) (string // Update the object we are trying to send to the server with the // correct resource version. - typeMeta, err := runtime.FindTypeMeta(obj) + typeMeta, err := meta.FindTypeMeta(obj) if err != nil { return "", err } @@ -149,7 +150,7 @@ func doDelete(c *client.RESTClient, resource string, obj runtime.Object) (string } func getIDFromObj(obj runtime.Object) (string, error) { - typeMeta, err := runtime.FindTypeMeta(obj) + typeMeta, err := meta.FindTypeMeta(obj) if err != nil { return "", err } @@ -157,7 +158,7 @@ func getIDFromObj(obj runtime.Object) (string, error) { } func getResourceVersionFromObj(obj runtime.Object) (string, error) { - typeMeta, err := runtime.FindTypeMeta(obj) + typeMeta, err := meta.FindTypeMeta(obj) if err != nil { return "", err } diff --git a/pkg/runtime/embedded_test.go b/pkg/runtime/embedded_test.go index 6fca4c41db0..c7b7c721d91 100644 --- a/pkg/runtime/embedded_test.go +++ b/pkg/runtime/embedded_test.go @@ -29,12 +29,14 @@ var Codec = runtime.CodecFor(scheme, "v1test") type EmbeddedTest struct { runtime.TypeMeta `yaml:",inline" json:",inline"` + ID string `yaml:"id,omitempty" json:"id,omitempty"` Object runtime.EmbeddedObject `yaml:"object,omitempty" json:"object,omitempty"` EmptyObject runtime.EmbeddedObject `yaml:"emptyObject,omitempty" json:"emptyObject,omitempty"` } type EmbeddedTestExternal struct { runtime.TypeMeta `yaml:",inline" json:",inline"` + ID string `yaml:"id,omitempty" json:"id,omitempty"` Object runtime.RawExtension `yaml:"object,omitempty" json:"object,omitempty"` EmptyObject runtime.RawExtension `yaml:"emptyObject,omitempty" json:"emptyObject,omitempty"` } @@ -49,9 +51,11 @@ func TestEmbeddedObject(t *testing.T) { outer := &EmbeddedTest{ TypeMeta: runtime.TypeMeta{Name: "outer"}, + ID: "outer", Object: runtime.EmbeddedObject{ &EmbeddedTest{ TypeMeta: runtime.TypeMeta{Name: "inner"}, + ID: "inner", }, }, } diff --git a/pkg/runtime/types.go b/pkg/runtime/types.go index f657861f7a8..7475444166b 100644 --- a/pkg/runtime/types.go +++ b/pkg/runtime/types.go @@ -26,8 +26,8 @@ import ( // TypeMeta is shared by all top level objects. The proper way to use it is to inline it in your type, // like this: // type MyAwesomeAPIObject struct { -// runtime.TypeMeta `yaml:",inline" json:",inline"` -// ... // other fields +// runtime.TypeMeta `yaml:",inline" json:",inline"` +// ... // other fields // } // func (*MyAwesomeAPIObject) IsAnAPIObject() {} // @@ -35,12 +35,13 @@ import ( // your own with the same fields. // type TypeMeta struct { - Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + Name string `json:"name,omitempty" yaml:"name,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"` } // PluginBase is like TypeMeta, but it's intended for plugin objects that won't ever be encoded diff --git a/pkg/tools/etcd_tools_test.go b/pkg/tools/etcd_tools_test.go index f899befb7c9..a784d425bbc 100644 --- a/pkg/tools/etcd_tools_test.go +++ b/pkg/tools/etcd_tools_test.go @@ -25,6 +25,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/coreos/go-etcd/etcd" @@ -44,7 +45,7 @@ func (*TestResource) IsAnAPIObject() {} var scheme *runtime.Scheme var codec runtime.Codec -var versioner = RuntimeVersionAdapter{runtime.NewTypeMetaResourceVersioner()} +var versioner = RuntimeVersionAdapter{meta.NewTypeMetaResourceVersioner()} func init() { scheme = runtime.NewScheme() From 1ccb86c7608a37b5b1a85f5509035eef2a4fda48 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Wed, 22 Oct 2014 22:54:34 -0400 Subject: [PATCH 2/5] Rename methods in api/meta to be cleaner --- cmd/kubecfg/kubecfg.go | 4 +- pkg/api/latest/latest.go | 4 +- pkg/api/meta/meta.go | 72 ++++++++++++++++----------------- pkg/api/meta/meta_test.go | 12 +++--- pkg/api/ref.go | 12 +++--- pkg/api/serialization_test.go | 4 +- pkg/apiserver/apiserver_test.go | 8 ++-- pkg/apiserver/resthandler.go | 10 ++--- pkg/client/cache/reflector.go | 14 +++---- pkg/kubectl/modify.go | 8 ++-- pkg/runtime/interfaces.go | 4 +- pkg/tools/etcd_tools_test.go | 2 +- 12 files changed, 77 insertions(+), 77 deletions(-) diff --git a/cmd/kubecfg/kubecfg.go b/cmd/kubecfg/kubecfg.go index c6c74546da5..65c7f05d850 100644 --- a/cmd/kubecfg/kubecfg.go +++ b/cmd/kubecfg/kubecfg.go @@ -373,7 +373,7 @@ func executeAPIRequest(ctx api.Context, method string, c *client.Client) bool { if err != nil { glog.Fatalf("error obtaining resource version for update: %v", err) } - jsonBase, err := meta.FindTypeMeta(obj) + jsonBase, err := meta.FindAccessor(obj) if err != nil { glog.Fatalf("error finding json base for update: %v", err) } @@ -409,7 +409,7 @@ func executeAPIRequest(ctx api.Context, method string, c *client.Client) bool { if err != nil { glog.Fatalf("error setting resource version: %v", err) } - jsonBase, err := meta.FindTypeMeta(obj) + jsonBase, err := meta.FindAccessor(obj) if err != nil { glog.Fatalf("error setting resource version: %v", err) } diff --git a/pkg/api/latest/latest.go b/pkg/api/latest/latest.go index 531a0067668..4c2bdc5d467 100644 --- a/pkg/api/latest/latest.go +++ b/pkg/api/latest/latest.go @@ -48,13 +48,13 @@ var Codec = v1beta1.Codec // 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.NewTypeMetaResourceVersioner() +var ResourceVersioner = meta.NewResourceVersioner() // 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.NewTypeMetaSelfLinker() +var SelfLinker = meta.NewSelfLinker() // VersionInterfaces contains the interfaces one should use for dealing with types of a particular version. type VersionInterfaces struct { diff --git a/pkg/api/meta/meta.go b/pkg/api/meta/meta.go index 6ce01543d17..449c500c4e3 100644 --- a/pkg/api/meta/meta.go +++ b/pkg/api/meta/meta.go @@ -24,9 +24,9 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" ) -// FindTypeMeta takes an arbitary api type, returns pointer to its TypeMeta field. +// FindAccessor takes an arbitary api type, returns pointer to its TypeMeta field. // obj must be a pointer to an api type. -func FindTypeMeta(obj runtime.Object) (TypeMetaInterface, error) { +func FindAccessor(obj runtime.Object) (Accessor, error) { v, err := conversion.EnforcePtr(obj) if err != nil { return nil, err @@ -38,7 +38,7 @@ func FindTypeMeta(obj runtime.Object) (TypeMetaInterface, error) { } typeMeta := v.FieldByName("TypeMeta") if !typeMeta.IsValid() { - return nil, fmt.Errorf("struct %v lacks embedded JSON type", name) + return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", name) } g, err := newGenericTypeMeta(typeMeta) if err != nil { @@ -47,67 +47,67 @@ func FindTypeMeta(obj runtime.Object) (TypeMetaInterface, error) { return g, nil } -// NewTypeMetaResourceVersioner returns a ResourceVersioner that can set or +// NewResourceVersioner returns a ResourceVersioner that can set or // retrieve ResourceVersion on objects derived from TypeMeta. -func NewTypeMetaResourceVersioner() runtime.ResourceVersioner { - return jsonBaseModifier{} +func NewResourceVersioner() runtime.ResourceVersioner { + return typeMetaModifier{} } -// jsonBaseModifier implements ResourceVersioner and SelfLinker. -type jsonBaseModifier struct{} +// typeMetaModifier implements ResourceVersioner and SelfLinker. +type typeMetaModifier struct{} -func (v jsonBaseModifier) ResourceVersion(obj runtime.Object) (string, error) { - json, err := FindTypeMeta(obj) +func (v typeMetaModifier) ResourceVersion(obj runtime.Object) (string, error) { + accessor, err := FindAccessor(obj) if err != nil { return "", err } - return json.ResourceVersion(), nil + return accessor.ResourceVersion(), nil } -func (v jsonBaseModifier) SetResourceVersion(obj runtime.Object, version string) error { - json, err := FindTypeMeta(obj) +func (v typeMetaModifier) SetResourceVersion(obj runtime.Object, version string) error { + accessor, err := FindAccessor(obj) if err != nil { return err } - json.SetResourceVersion(version) + accessor.SetResourceVersion(version) return nil } -func (v jsonBaseModifier) ID(obj runtime.Object) (string, error) { - json, err := FindTypeMeta(obj) +func (v typeMetaModifier) Name(obj runtime.Object) (string, error) { + accessor, err := FindAccessor(obj) if err != nil { return "", err } - return json.ID(), nil + return accessor.Name(), nil } -func (v jsonBaseModifier) SelfLink(obj runtime.Object) (string, error) { - json, err := FindTypeMeta(obj) +func (v typeMetaModifier) SelfLink(obj runtime.Object) (string, error) { + accessor, err := FindAccessor(obj) if err != nil { return "", err } - return json.SelfLink(), nil + return accessor.SelfLink(), nil } -func (v jsonBaseModifier) SetSelfLink(obj runtime.Object, selfLink string) error { - json, err := FindTypeMeta(obj) +func (v typeMetaModifier) SetSelfLink(obj runtime.Object, selfLink string) error { + accessor, err := FindAccessor(obj) if err != nil { return err } - json.SetSelfLink(selfLink) + accessor.SetSelfLink(selfLink) return nil } -// NewTypeMetaSelfLinker returns a SelfLinker that works on all TypeMeta SelfLink fields. -func NewTypeMetaSelfLinker() runtime.SelfLinker { - return jsonBaseModifier{} +// NewSelfLinker returns a SelfLinker that works on all TypeMeta SelfLink fields. +func NewSelfLinker() runtime.SelfLinker { + return typeMetaModifier{} } -// TypeMetaInterface lets you work with a TypeMeta from any of the versioned or +// Accessor lets you work with object metadata from any of the versioned or // internal APIruntime.Objects. -type TypeMetaInterface interface { - ID() string - SetID(ID string) +type Accessor interface { + Name() string + SetName(name string) APIVersion() string SetAPIVersion(version string) Kind() string @@ -119,19 +119,19 @@ type TypeMetaInterface interface { } type genericTypeMeta struct { - id *string + name *string apiVersion *string kind *string resourceVersion *string selfLink *string } -func (g genericTypeMeta) ID() string { - return *g.id +func (g genericTypeMeta) Name() string { + return *g.name } -func (g genericTypeMeta) SetID(id string) { - *g.id = id +func (g genericTypeMeta) SetName(name string) { + *g.name = name } func (g genericTypeMeta) APIVersion() string { @@ -196,7 +196,7 @@ func fieldPtr(v reflect.Value, fieldName string, dest interface{}) error { // Returns an error if this isn't the case. func newGenericTypeMeta(v reflect.Value) (genericTypeMeta, error) { g := genericTypeMeta{} - if err := fieldPtr(v, "Name", &g.id); err != nil { + if err := fieldPtr(v, "Name", &g.name); err != nil { return g, err } if err := fieldPtr(v, "APIVersion", &g.apiVersion); err != nil { diff --git a/pkg/api/meta/meta_test.go b/pkg/api/meta/meta_test.go index 156d19e3c44..daf6d471246 100644 --- a/pkg/api/meta/meta_test.go +++ b/pkg/api/meta/meta_test.go @@ -44,9 +44,9 @@ func TestGenericTypeMeta(t *testing.T) { if err != nil { t.Fatalf("new err: %v", err) } - // Prove g supports TypeMetaInterface. - jbi := TypeMetaInterface(g) - if e, a := "foo", jbi.ID(); e != a { + // Prove g supports Accessor. + jbi := Accessor(g) + if e, a := "foo", jbi.Name(); e != a { t.Errorf("expected %v, got %v", e, a) } if e, a := "a", jbi.APIVersion(); e != a { @@ -62,7 +62,7 @@ func TestGenericTypeMeta(t *testing.T) { t.Errorf("expected %v, got %v", e, a) } - jbi.SetID("bar") + jbi.SetName("bar") jbi.SetAPIVersion("c") jbi.SetKind("d") jbi.SetResourceVersion("2") @@ -107,7 +107,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 := NewTypeMetaResourceVersioner() + versioning := NewResourceVersioner() for key, testCase := range testCases { actual, err := versioning.ResourceVersion(testCase.Object) if err != nil { @@ -170,7 +170,7 @@ func TestTypeMetaSelfLinker(t *testing.T) { }, } - linker := NewTypeMetaSelfLinker() + linker := NewSelfLinker() 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/ref.go b/pkg/api/ref.go index b8ad6153f6e..2e56d3aa5be 100644 --- a/pkg/api/ref.go +++ b/pkg/api/ref.go @@ -36,7 +36,7 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) { if obj == nil { return nil, ErrNilObject } - jsonBase, err := meta.FindTypeMeta(obj) + accessor, err := meta.FindAccessor(obj) if err != nil { return nil, err } @@ -44,16 +44,16 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) { if err != nil { return nil, err } - version := versionFromSelfLink.FindStringSubmatch(jsonBase.SelfLink()) + version := versionFromSelfLink.FindStringSubmatch(accessor.SelfLink()) if len(version) < 2 { - return nil, fmt.Errorf("unexpected self link format: %v", jsonBase.SelfLink()) + return nil, fmt.Errorf("unexpected self link format: %v", accessor.SelfLink()) } return &ObjectReference{ Kind: kind, APIVersion: version[1], // TODO: correct Name and UID when TypeMeta makes a distinction - Name: jsonBase.ID(), - UID: jsonBase.ID(), - ResourceVersion: jsonBase.ResourceVersion(), + Name: accessor.Name(), + UID: accessor.Name(), + ResourceVersion: accessor.ResourceVersion(), }, nil } diff --git a/pkg/api/serialization_test.go b/pkg/api/serialization_test.go index fa3f9e51587..7c242604dae 100644 --- a/pkg/api/serialization_test.go +++ b/pkg/api/serialization_test.go @@ -101,7 +101,7 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs( func runTest(t *testing.T, codec runtime.Codec, source runtime.Object) { name := reflect.TypeOf(source).Elem().Name() apiObjectFuzzer.Fuzz(source) - j, err := meta.FindTypeMeta(source) + j, err := meta.FindAccessor(source) if err != nil { t.Fatalf("Unexpected error %v for %#v", err, source) } @@ -160,7 +160,7 @@ func TestTypes(t *testing.T) { t.Errorf("Couldn't make a %v? %v", kind, err) continue } - if _, err := meta.FindTypeMeta(item); err != nil { + if _, err := meta.FindAccessor(item); err != nil { t.Logf("%s is not a TypeMeta and cannot be round tripped: %v", kind, err) continue } diff --git a/pkg/apiserver/apiserver_test.go b/pkg/apiserver/apiserver_test.go index 4a485e9c781..fddd2a1c8fd 100644 --- a/pkg/apiserver/apiserver_test.go +++ b/pkg/apiserver/apiserver_test.go @@ -564,11 +564,11 @@ func TestParseTimeout(t *testing.T) { type setTestSelfLinker struct { t *testing.T expectedSet string - id string + name string called bool } -func (s *setTestSelfLinker) ID(runtime.Object) (string, error) { return s.id, nil } +func (s *setTestSelfLinker) Name(runtime.Object) (string, error) { return s.name, nil } func (*setTestSelfLinker) SelfLink(runtime.Object) (string, error) { return "", nil } func (s *setTestSelfLinker) SetSelfLink(obj runtime.Object, selfLink string) error { if e, a := s.expectedSet, selfLink; e != a { @@ -587,7 +587,7 @@ func TestSyncCreate(t *testing.T) { } selfLinker := &setTestSelfLinker{ t: t, - id: "bar", + name: "bar", expectedSet: "/prefix/version/foo/bar", } handler := Handle(map[string]RESTStorage{ @@ -684,7 +684,7 @@ func TestAsyncCreateError(t *testing.T) { } selfLinker := &setTestSelfLinker{ t: t, - id: "bar", + name: "bar", expectedSet: "/prefix/version/foo/bar", } handler := Handle(map[string]RESTStorage{"foo": &storage}, codec, "/prefix/version", selfLinker) diff --git a/pkg/apiserver/resthandler.go b/pkg/apiserver/resthandler.go index 0f368305ec1..edbcaa52371 100644 --- a/pkg/apiserver/resthandler.go +++ b/pkg/apiserver/resthandler.go @@ -64,14 +64,14 @@ func (h *RESTHandler) setSelfLink(obj runtime.Object, req *http.Request) error { return h.selfLinker.SetSelfLink(obj, newURL.String()) } -// Like setSelfLink, but appends the object's id. -func (h *RESTHandler) setSelfLinkAddID(obj runtime.Object, req *http.Request) error { - id, err := h.selfLinker.ID(obj) +// Like setSelfLink, but appends the object's name. +func (h *RESTHandler) setSelfLinkAddName(obj runtime.Object, req *http.Request) error { + name, err := h.selfLinker.Name(obj) if err != nil { return err } newURL := *req.URL - newURL.Path = path.Join(h.canonicalPrefix, req.URL.Path, id) + newURL.Path = path.Join(h.canonicalPrefix, req.URL.Path, name) newURL.RawQuery = "" newURL.Fragment = "" return h.selfLinker.SetSelfLink(obj, newURL.String()) @@ -171,7 +171,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt errorJSON(err, h.codec, w) return } - op := h.createOperation(out, sync, timeout, curry(h.setSelfLinkAddID, req)) + op := h.createOperation(out, sync, timeout, curry(h.setSelfLinkAddName, req)) h.finishReq(op, req, w) case "DELETE": diff --git a/pkg/client/cache/reflector.go b/pkg/client/cache/reflector.go index 243d56db864..d9036a716be 100644 --- a/pkg/client/cache/reflector.go +++ b/pkg/client/cache/reflector.go @@ -79,7 +79,7 @@ func (r *Reflector) listAndWatch() { glog.Errorf("Failed to list %v: %v", r.expectedType, err) return } - jsonBase, err := meta.FindTypeMeta(list) + jsonBase, err := meta.FindAccessor(list) if err != nil { glog.Errorf("Unable to understand list result %#v", list) return @@ -113,11 +113,11 @@ func (r *Reflector) listAndWatch() { func (r *Reflector) syncWith(items []runtime.Object) error { found := map[string]interface{}{} for _, item := range items { - jsonBase, err := meta.FindTypeMeta(item) + jsonBase, err := meta.FindAccessor(item) if err != nil { return fmt.Errorf("unexpected item in list: %v", err) } - found[jsonBase.ID()] = item + found[jsonBase.Name()] = item } r.store.Replace(found) @@ -140,21 +140,21 @@ func (r *Reflector) watchHandler(w watch.Interface, resourceVersion *string) err glog.Errorf("expected type %v, but watch event object had type %v", e, a) continue } - jsonBase, err := meta.FindTypeMeta(event.Object) + jsonBase, err := meta.FindAccessor(event.Object) if err != nil { glog.Errorf("unable to understand watch event %#v", event) continue } switch event.Type { case watch.Added: - r.store.Add(jsonBase.ID(), event.Object) + r.store.Add(jsonBase.Name(), event.Object) case watch.Modified: - r.store.Update(jsonBase.ID(), event.Object) + r.store.Update(jsonBase.Name(), event.Object) case watch.Deleted: // TODO: Will any consumers need access to the "last known // state", which is passed in event.Object? If so, may need // to change this. - r.store.Delete(jsonBase.ID()) + r.store.Delete(jsonBase.Name()) default: glog.Errorf("unable to understand watch event %#v", event) } diff --git a/pkg/kubectl/modify.go b/pkg/kubectl/modify.go index c0dfe277446..c7420abc642 100644 --- a/pkg/kubectl/modify.go +++ b/pkg/kubectl/modify.go @@ -110,7 +110,7 @@ func doUpdate(c *client.RESTClient, resource string, obj runtime.Object) (string // Update the object we are trying to send to the server with the // correct resource version. - typeMeta, err := meta.FindTypeMeta(obj) + typeMeta, err := meta.FindAccessor(obj) if err != nil { return "", err } @@ -150,15 +150,15 @@ func doDelete(c *client.RESTClient, resource string, obj runtime.Object) (string } func getIDFromObj(obj runtime.Object) (string, error) { - typeMeta, err := meta.FindTypeMeta(obj) + typeMeta, err := meta.FindAccessor(obj) if err != nil { return "", err } - return typeMeta.ID(), nil + return typeMeta.Name(), nil } func getResourceVersionFromObj(obj runtime.Object) (string, error) { - typeMeta, err := meta.FindTypeMeta(obj) + typeMeta, err := meta.FindAccessor(obj) if err != nil { return "", err } diff --git a/pkg/runtime/interfaces.go b/pkg/runtime/interfaces.go index b688f0ae48b..5d5e725d687 100644 --- a/pkg/runtime/interfaces.go +++ b/pkg/runtime/interfaces.go @@ -45,8 +45,8 @@ type SelfLinker interface { SetSelfLink(obj Object, selfLink string) error SelfLink(obj Object) (string, error) - // Knowing ID is sometimes necessary to use a SelfLinker. - ID(obj Object) (string, error) + // Knowing Name is sometimes necessary to use a SelfLinker. + Name(obj Object) (string, error) } // All api types must support the Object interface. It's deliberately tiny so that this is not an onerous diff --git a/pkg/tools/etcd_tools_test.go b/pkg/tools/etcd_tools_test.go index a784d425bbc..2ac4897cbf3 100644 --- a/pkg/tools/etcd_tools_test.go +++ b/pkg/tools/etcd_tools_test.go @@ -45,7 +45,7 @@ func (*TestResource) IsAnAPIObject() {} var scheme *runtime.Scheme var codec runtime.Codec -var versioner = RuntimeVersionAdapter{meta.NewTypeMetaResourceVersioner()} +var versioner = RuntimeVersionAdapter{meta.NewResourceVersioner()} func init() { scheme = runtime.NewScheme() From 35eaf90255dfe7673e91e7f293fde30c395bcffb Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Wed, 22 Oct 2014 22:59:15 -0400 Subject: [PATCH 3/5] Add UID to MetaAccessor and Ref --- pkg/api/meta/meta.go | 14 ++++++++++++++ pkg/api/meta/meta_test.go | 9 +++++++++ pkg/api/ref.go | 2 +- pkg/api/ref_test.go | 6 ++++-- pkg/client/record/event_test.go | 5 +++-- pkg/runtime/types.go | 1 + 6 files changed, 32 insertions(+), 5 deletions(-) diff --git a/pkg/api/meta/meta.go b/pkg/api/meta/meta.go index 449c500c4e3..12d9ce3c044 100644 --- a/pkg/api/meta/meta.go +++ b/pkg/api/meta/meta.go @@ -108,6 +108,8 @@ func NewSelfLinker() runtime.SelfLinker { type Accessor interface { Name() string SetName(name string) + UID() string + SetUID(uid string) APIVersion() string SetAPIVersion(version string) Kind() string @@ -120,6 +122,7 @@ type Accessor interface { type genericTypeMeta struct { name *string + uid *string apiVersion *string kind *string resourceVersion *string @@ -134,6 +137,14 @@ func (g genericTypeMeta) SetName(name string) { *g.name = name } +func (g genericTypeMeta) UID() string { + return *g.uid +} + +func (g genericTypeMeta) SetUID(uid string) { + *g.uid = uid +} + func (g genericTypeMeta) APIVersion() string { return *g.apiVersion } @@ -199,6 +210,9 @@ func newGenericTypeMeta(v reflect.Value) (genericTypeMeta, error) { if err := fieldPtr(v, "Name", &g.name); err != nil { return g, err } + if err := fieldPtr(v, "UID", &g.uid); err != nil { + return g, err + } if err := fieldPtr(v, "APIVersion", &g.apiVersion); err != nil { return g, err } diff --git a/pkg/api/meta/meta_test.go b/pkg/api/meta/meta_test.go index daf6d471246..1acb7ebf65f 100644 --- a/pkg/api/meta/meta_test.go +++ b/pkg/api/meta/meta_test.go @@ -28,6 +28,7 @@ func TestGenericTypeMeta(t *testing.T) { type TypeMeta struct { Kind string `json:"kind,omitempty" yaml:"kind,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"` @@ -35,6 +36,7 @@ func TestGenericTypeMeta(t *testing.T) { } j := TypeMeta{ Name: "foo", + UID: "uid", APIVersion: "a", Kind: "b", ResourceVersion: "1", @@ -49,6 +51,9 @@ func TestGenericTypeMeta(t *testing.T) { if e, a := "foo", jbi.Name(); e != a { t.Errorf("expected %v, got %v", e, a) } + if e, a := "uid", jbi.UID(); e != a { + t.Errorf("expected %v, got %v", e, a) + } if e, a := "a", jbi.APIVersion(); e != a { t.Errorf("expected %v, got %v", e, a) } @@ -63,6 +68,7 @@ func TestGenericTypeMeta(t *testing.T) { } jbi.SetName("bar") + jbi.SetUID("other") jbi.SetAPIVersion("c") jbi.SetKind("d") jbi.SetResourceVersion("2") @@ -72,6 +78,9 @@ func TestGenericTypeMeta(t *testing.T) { if e, a := "bar", j.Name; e != a { t.Errorf("expected %v, got %v", e, a) } + if e, a := "other", j.UID; e != a { + t.Errorf("expected %v, got %v", e, a) + } if e, a := "c", j.APIVersion; e != a { t.Errorf("expected %v, got %v", e, a) } diff --git a/pkg/api/ref.go b/pkg/api/ref.go index 2e56d3aa5be..200fa34b557 100644 --- a/pkg/api/ref.go +++ b/pkg/api/ref.go @@ -53,7 +53,7 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) { APIVersion: version[1], // TODO: correct Name and UID when TypeMeta makes a distinction Name: accessor.Name(), - UID: accessor.Name(), + UID: accessor.UID(), ResourceVersion: accessor.ResourceVersion(), }, nil } diff --git a/pkg/api/ref_test.go b/pkg/api/ref_test.go index 14be5bb1600..fefb668c8a5 100644 --- a/pkg/api/ref_test.go +++ b/pkg/api/ref_test.go @@ -37,6 +37,7 @@ func TestGetReference(t *testing.T) { obj: &Pod{ TypeMeta: TypeMeta{ Name: "foo", + UID: "bar", ResourceVersion: "42", SelfLink: "/api/v1beta1/pods/foo", }, @@ -45,7 +46,7 @@ func TestGetReference(t *testing.T) { Kind: "Pod", APIVersion: "v1beta1", Name: "foo", - UID: "foo", + UID: "bar", ResourceVersion: "42", }, }, @@ -53,6 +54,7 @@ func TestGetReference(t *testing.T) { obj: &ServiceList{ TypeMeta: TypeMeta{ Name: "foo", + UID: "bar", ResourceVersion: "42", SelfLink: "/api/v1beta2/services", }, @@ -61,7 +63,7 @@ func TestGetReference(t *testing.T) { Kind: "ServiceList", APIVersion: "v1beta2", Name: "foo", - UID: "foo", + UID: "bar", ResourceVersion: "42", }, }, diff --git a/pkg/client/record/event_test.go b/pkg/client/record/event_test.go index 9c58b23ec18..d515d28d0bf 100644 --- a/pkg/client/record/event_test.go +++ b/pkg/client/record/event_test.go @@ -57,6 +57,7 @@ func TestEventf(t *testing.T) { TypeMeta: api.TypeMeta{ SelfLink: "/api/v1beta1/pods/foo", Name: "foo", + UID: "bar", }, }, fieldPath: "desiredState.manifest.containers[2]", @@ -68,7 +69,7 @@ func TestEventf(t *testing.T) { InvolvedObject: api.ObjectReference{ Kind: "Pod", Name: "foo", - UID: "foo", + UID: "bar", APIVersion: "v1beta1", FieldPath: "desiredState.manifest.containers[2]", }, @@ -77,7 +78,7 @@ func TestEventf(t *testing.T) { Message: "some verbose message: 1", Source: "eventTest", }, - expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"", Name:"foo", UID:"foo", APIVersion:"v1beta1", ResourceVersion:"", FieldPath:"desiredState.manifest.containers[2]"}): status: 'running', reason: 'started' some verbose message: 1`, + expectLog: `Event(api.ObjectReference{Kind:"Pod", Namespace:"", Name:"foo", UID:"bar", APIVersion:"v1beta1", ResourceVersion:"", FieldPath:"desiredState.manifest.containers[2]"}): status: 'running', reason: 'started' some verbose message: 1`, }, } diff --git a/pkg/runtime/types.go b/pkg/runtime/types.go index 7475444166b..c20c6a9df74 100644 --- a/pkg/runtime/types.go +++ b/pkg/runtime/types.go @@ -39,6 +39,7 @@ type TypeMeta struct { Kind string `json:"kind,omitempty" yaml:"kind,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"` From e5c924585c1f4e6280bb6cb419c22087a1e045f3 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Wed, 22 Oct 2014 23:55:19 -0400 Subject: [PATCH 4/5] Add support for ObjectMeta and ListMeta lookup --- pkg/api/meta/meta.go | 178 ++++++++++++++++++++++------------ pkg/api/meta/meta_test.go | 197 +++++++++++++++++++++++++++++++++----- 2 files changed, 288 insertions(+), 87 deletions(-) diff --git a/pkg/api/meta/meta.go b/pkg/api/meta/meta.go index 12d9ce3c044..a4570987f5a 100644 --- a/pkg/api/meta/meta.go +++ b/pkg/api/meta/meta.go @@ -24,9 +24,10 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" ) -// FindAccessor takes an arbitary api type, returns pointer to its TypeMeta field. -// obj must be a pointer to an api type. -func FindAccessor(obj runtime.Object) (Accessor, error) { +// FindAccessor takes an arbitary type and returns an Accessor interfaces. +// obj must be a pointer to an api type. An error is returned if the minimum +// required fields are missing. +func FindAccessor(obj interface{}) (Accessor, error) { v, err := conversion.EnforcePtr(obj) if err != nil { return nil, err @@ -36,27 +37,51 @@ func FindAccessor(obj runtime.Object) (Accessor, error) { if v.Kind() != reflect.Struct { return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), name, v.Interface()) } + typeMeta := v.FieldByName("TypeMeta") if !typeMeta.IsValid() { return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", name) } - g, err := newGenericTypeMeta(typeMeta) - if err != nil { - return nil, err + + a := &genericAccessor{} + if err := findTypeMeta(typeMeta, a); err != nil { + return nil, fmt.Errorf("unable to find type fields on %#v", typeMeta) } - return g, nil + + objectMeta := v.FieldByName("ObjectMeta") + if objectMeta.IsValid() { + // look for the ObjectMeta fields + if err := findObjectMeta(objectMeta, a); err != nil { + return nil, fmt.Errorf("unable to find object fields on %#v", objectMeta) + } + } else { + listMeta := v.FieldByName("ListMeta") + if listMeta.IsValid() { + // look for the ListMeta fields + if err := findListMeta(listMeta, a); err != nil { + return nil, fmt.Errorf("unable to find list fields on %#v", listMeta) + } + } else { + // look for the older TypeMeta with all metadata + if err := findObjectMeta(typeMeta, a); err != nil { + return nil, fmt.Errorf("unable to find object fields on %#v", typeMeta) + } + } + } + + return a, nil } // NewResourceVersioner returns a ResourceVersioner that can set or // retrieve ResourceVersion on objects derived from TypeMeta. func NewResourceVersioner() runtime.ResourceVersioner { - return typeMetaModifier{} + return resourceAccessor{} } -// typeMetaModifier implements ResourceVersioner and SelfLinker. -type typeMetaModifier struct{} +// resourceAccessor implements ResourceVersioner and SelfLinker. +type resourceAccessor struct{} -func (v typeMetaModifier) ResourceVersion(obj runtime.Object) (string, error) { +func (v resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) { accessor, err := FindAccessor(obj) if err != nil { return "", err @@ -64,7 +89,7 @@ func (v typeMetaModifier) ResourceVersion(obj runtime.Object) (string, error) { return accessor.ResourceVersion(), nil } -func (v typeMetaModifier) SetResourceVersion(obj runtime.Object, version string) error { +func (v resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error { accessor, err := FindAccessor(obj) if err != nil { return err @@ -73,7 +98,7 @@ func (v typeMetaModifier) SetResourceVersion(obj runtime.Object, version string) return nil } -func (v typeMetaModifier) Name(obj runtime.Object) (string, error) { +func (v resourceAccessor) Name(obj runtime.Object) (string, error) { accessor, err := FindAccessor(obj) if err != nil { return "", err @@ -81,7 +106,7 @@ func (v typeMetaModifier) Name(obj runtime.Object) (string, error) { return accessor.Name(), nil } -func (v typeMetaModifier) SelfLink(obj runtime.Object) (string, error) { +func (v resourceAccessor) SelfLink(obj runtime.Object) (string, error) { accessor, err := FindAccessor(obj) if err != nil { return "", err @@ -89,7 +114,7 @@ func (v typeMetaModifier) SelfLink(obj runtime.Object) (string, error) { return accessor.SelfLink(), nil } -func (v typeMetaModifier) SetSelfLink(obj runtime.Object, selfLink string) error { +func (v resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error { accessor, err := FindAccessor(obj) if err != nil { return err @@ -100,7 +125,7 @@ func (v typeMetaModifier) SetSelfLink(obj runtime.Object, selfLink string) error // NewSelfLinker returns a SelfLinker that works on all TypeMeta SelfLink fields. func NewSelfLinker() runtime.SelfLinker { - return typeMetaModifier{} + return resourceAccessor{} } // Accessor lets you work with object metadata from any of the versioned or @@ -120,7 +145,9 @@ type Accessor interface { SetSelfLink(selfLink string) } -type genericTypeMeta struct { +// genericAccessor contains pointers to strings that can modify an arbitrary +// struct and implements the Accessor interface. +type genericAccessor struct { name *string uid *string apiVersion *string @@ -129,52 +156,64 @@ type genericTypeMeta struct { selfLink *string } -func (g genericTypeMeta) Name() string { - return *g.name +func (a genericAccessor) Name() string { + if a.name == nil { + return "" + } + return *a.name } -func (g genericTypeMeta) SetName(name string) { - *g.name = name +func (a genericAccessor) SetName(name string) { + if a.name == nil { + return + } + *a.name = name } -func (g genericTypeMeta) UID() string { - return *g.uid +func (a genericAccessor) UID() string { + if a.uid == nil { + return "" + } + return *a.uid } -func (g genericTypeMeta) SetUID(uid string) { - *g.uid = uid +func (a genericAccessor) SetUID(uid string) { + if a.uid == nil { + return + } + *a.uid = uid } -func (g genericTypeMeta) APIVersion() string { - return *g.apiVersion +func (a genericAccessor) APIVersion() string { + return *a.apiVersion } -func (g genericTypeMeta) SetAPIVersion(version string) { - *g.apiVersion = version +func (a genericAccessor) SetAPIVersion(version string) { + *a.apiVersion = version } -func (g genericTypeMeta) Kind() string { - return *g.kind +func (a genericAccessor) Kind() string { + return *a.kind } -func (g genericTypeMeta) SetKind(kind string) { - *g.kind = kind +func (a genericAccessor) SetKind(kind string) { + *a.kind = kind } -func (g genericTypeMeta) ResourceVersion() string { - return *g.resourceVersion +func (a genericAccessor) ResourceVersion() string { + return *a.resourceVersion } -func (g genericTypeMeta) SetResourceVersion(version string) { - *g.resourceVersion = version +func (a genericAccessor) SetResourceVersion(version string) { + *a.resourceVersion = version } -func (g genericTypeMeta) SelfLink() string { - return *g.selfLink +func (a genericAccessor) SelfLink() string { + return *a.selfLink } -func (g genericTypeMeta) SetSelfLink(selfLink string) { - *g.selfLink = selfLink +func (a genericAccessor) SetSelfLink(selfLink string) { + *a.selfLink = selfLink } // fieldPtr puts the address of fieldName, which must be a member of v, @@ -202,28 +241,41 @@ func fieldPtr(v reflect.Value, fieldName string, dest interface{}) error { return fmt.Errorf("Couldn't assign/convert %v to %v", field.Type(), v.Type()) } -// newGenericTypeMeta creates a new generic TypeMeta from v, which must be an -// addressable/setable reflect.Value having the same fields as api.TypeMeta. -// Returns an error if this isn't the case. -func newGenericTypeMeta(v reflect.Value) (genericTypeMeta, error) { - g := genericTypeMeta{} - if err := fieldPtr(v, "Name", &g.name); err != nil { - return g, err +// findTypeMeta extracts pointers to version and kind fields from an object +func findTypeMeta(v reflect.Value, a *genericAccessor) error { + if err := fieldPtr(v, "APIVersion", &a.apiVersion); err != nil { + return err } - if err := fieldPtr(v, "UID", &g.uid); err != nil { - return g, err + if err := fieldPtr(v, "Kind", &a.kind); err != nil { + return err } - if err := fieldPtr(v, "APIVersion", &g.apiVersion); err != nil { - return g, err - } - if err := fieldPtr(v, "Kind", &g.kind); err != nil { - return g, err - } - if err := fieldPtr(v, "ResourceVersion", &g.resourceVersion); err != nil { - return g, err - } - if err := fieldPtr(v, "SelfLink", &g.selfLink); err != nil { - return g, err - } - return g, nil + return nil +} + +// findObjectMeta extracts pointers to metadata fields from an object +func findObjectMeta(v reflect.Value, a *genericAccessor) error { + if err := fieldPtr(v, "Name", &a.name); err != nil { + return err + } + if err := fieldPtr(v, "UID", &a.uid); err != nil { + return err + } + if err := fieldPtr(v, "ResourceVersion", &a.resourceVersion); err != nil { + return err + } + if err := fieldPtr(v, "SelfLink", &a.selfLink); err != nil { + return err + } + return nil +} + +// findObjectMeta extracts pointers to metadata fields from a list object +func findListMeta(v reflect.Value, a *genericAccessor) error { + if err := fieldPtr(v, "ResourceVersion", &a.resourceVersion); err != nil { + return err + } + if err := fieldPtr(v, "SelfLink", &a.selfLink); err != nil { + return err + } + return nil } diff --git a/pkg/api/meta/meta_test.go b/pkg/api/meta/meta_test.go index 1acb7ebf65f..094b231f015 100644 --- a/pkg/api/meta/meta_test.go +++ b/pkg/api/meta/meta_test.go @@ -17,7 +17,6 @@ limitations under the License. package meta import ( - "reflect" "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" @@ -34,47 +33,50 @@ func TestGenericTypeMeta(t *testing.T) { ResourceVersion string `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"` APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` } - j := TypeMeta{ - Name: "foo", - UID: "uid", - APIVersion: "a", - Kind: "b", - ResourceVersion: "1", - SelfLink: "some/place/only/we/know", + type Object struct { + TypeMeta `json:",inline" yaml:",inline"` } - g, err := newGenericTypeMeta(reflect.ValueOf(&j).Elem()) + j := Object{ + TypeMeta{ + Name: "foo", + UID: "uid", + APIVersion: "a", + Kind: "b", + ResourceVersion: "1", + SelfLink: "some/place/only/we/know", + }, + } + accessor, err := FindAccessor(&j) if err != nil { t.Fatalf("new err: %v", err) } - // Prove g supports Accessor. - jbi := Accessor(g) - if e, a := "foo", jbi.Name(); e != a { + if e, a := "foo", accessor.Name(); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := "uid", jbi.UID(); e != a { + if e, a := "uid", accessor.UID(); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := "a", jbi.APIVersion(); e != a { + if e, a := "a", accessor.APIVersion(); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := "b", jbi.Kind(); e != a { + if e, a := "b", accessor.Kind(); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := "1", jbi.ResourceVersion(); e != a { + if e, a := "1", accessor.ResourceVersion(); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := "some/place/only/we/know", jbi.SelfLink(); e != a { + if e, a := "some/place/only/we/know", accessor.SelfLink(); e != a { t.Errorf("expected %v, got %v", e, a) } - jbi.SetName("bar") - jbi.SetUID("other") - jbi.SetAPIVersion("c") - jbi.SetKind("d") - jbi.SetResourceVersion("2") - jbi.SetSelfLink("google.com") + accessor.SetName("bar") + accessor.SetUID("other") + accessor.SetAPIVersion("c") + accessor.SetKind("d") + accessor.SetResourceVersion("2") + accessor.SetSelfLink("google.com") - // Prove that jbi changes the original object. + // Prove that accessor changes the original object. if e, a := "bar", j.Name; e != a { t.Errorf("expected %v, got %v", e, a) } @@ -95,6 +97,153 @@ func TestGenericTypeMeta(t *testing.T) { } } +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 { + 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"` + } + type Object struct { + TypeMeta `json:",inline" yaml:",inline"` + ObjectMeta `json:"metadata" yaml:"metadata"` + } + j := Object{ + TypeMeta{ + APIVersion: "a", + Kind: "b", + }, + ObjectMeta{ + Name: "foo", + UID: "uid", + ResourceVersion: "1", + SelfLink: "some/place/only/we/know", + }, + } + accessor, err := FindAccessor(&j) + if err != nil { + t.Fatalf("new err: %v", err) + } + if e, a := "foo", accessor.Name(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "uid", accessor.UID(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "a", accessor.APIVersion(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "b", accessor.Kind(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "1", accessor.ResourceVersion(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "some/place/only/we/know", accessor.SelfLink(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + + accessor.SetName("bar") + accessor.SetUID("other") + accessor.SetAPIVersion("c") + accessor.SetKind("d") + accessor.SetResourceVersion("2") + accessor.SetSelfLink("google.com") + + // Prove that accessor changes the original object. + if e, a := "bar", j.Name; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "other", j.UID; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "c", j.APIVersion; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "d", j.Kind; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "2", j.ResourceVersion; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "google.com", j.SelfLink; e != a { + t.Errorf("expected %v, got %v", e, a) + } +} + +func TestGenericListMeta(t *testing.T) { + type TypeMeta struct { + Kind string `json:"kind,omitempty" yaml:"kind,omitempty"` + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + } + type ListMeta struct { + SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"` + ResourceVersion string `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"` + } + type Object struct { + TypeMeta `json:",inline" yaml:",inline"` + ListMeta `json:"metadata" yaml:"metadata"` + } + j := Object{ + TypeMeta{ + APIVersion: "a", + Kind: "b", + }, + ListMeta{ + ResourceVersion: "1", + SelfLink: "some/place/only/we/know", + }, + } + accessor, err := FindAccessor(&j) + if err != nil { + t.Fatalf("new err: %v", err) + } + if e, a := "", accessor.Name(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "", accessor.UID(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "a", accessor.APIVersion(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "b", accessor.Kind(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "1", accessor.ResourceVersion(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "some/place/only/we/know", accessor.SelfLink(); e != a { + t.Errorf("expected %v, got %v", e, a) + } + + accessor.SetName("bar") + accessor.SetUID("other") + accessor.SetAPIVersion("c") + accessor.SetKind("d") + accessor.SetResourceVersion("2") + accessor.SetSelfLink("google.com") + + // Prove that accessor changes the original object. + if e, a := "c", j.APIVersion; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "d", j.Kind; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "2", j.ResourceVersion; e != a { + t.Errorf("expected %v, got %v", e, a) + } + if e, a := "google.com", j.SelfLink; e != a { + t.Errorf("expected %v, got %v", e, a) + } +} + type MyAPIObject struct { runtime.TypeMeta `yaml:",inline" json:",inline"` } From 3df1c2f29dee2f3c06e9461807ae98e255f673e0 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Thu, 23 Oct 2014 18:01:25 -0400 Subject: [PATCH 5/5] Use meta.Interface and meta.Accessor --- cmd/kubecfg/kubecfg.go | 6 +-- pkg/api/meta/meta.go | 78 +++++++++++++++++------------------ pkg/api/meta/meta_test.go | 6 +-- pkg/api/ref.go | 12 +++--- pkg/api/serialization_test.go | 4 +- pkg/client/cache/reflector.go | 18 ++++---- pkg/kubectl/modify.go | 12 +++--- 7 files changed, 68 insertions(+), 68 deletions(-) diff --git a/cmd/kubecfg/kubecfg.go b/cmd/kubecfg/kubecfg.go index 65c7f05d850..87c96b13bf6 100644 --- a/cmd/kubecfg/kubecfg.go +++ b/cmd/kubecfg/kubecfg.go @@ -373,11 +373,11 @@ func executeAPIRequest(ctx api.Context, method string, c *client.Client) bool { if err != nil { glog.Fatalf("error obtaining resource version for update: %v", err) } - jsonBase, err := meta.FindAccessor(obj) + meta, err := meta.Accessor(obj) if err != nil { glog.Fatalf("error finding json base for update: %v", err) } - version = jsonBase.ResourceVersion() + version = meta.ResourceVersion() verb = "PUT" setBody = true if !validStorage || !hasSuffix { @@ -409,7 +409,7 @@ func executeAPIRequest(ctx api.Context, method string, c *client.Client) bool { if err != nil { glog.Fatalf("error setting resource version: %v", err) } - jsonBase, err := meta.FindAccessor(obj) + jsonBase, err := meta.Accessor(obj) if err != nil { glog.Fatalf("error setting resource version: %v", err) } diff --git a/pkg/api/meta/meta.go b/pkg/api/meta/meta.go index a4570987f5a..6509fbabfd7 100644 --- a/pkg/api/meta/meta.go +++ b/pkg/api/meta/meta.go @@ -24,46 +24,63 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" ) -// FindAccessor takes an arbitary type and returns an Accessor interfaces. -// obj must be a pointer to an api type. An error is returned if the minimum -// required fields are missing. -func FindAccessor(obj interface{}) (Accessor, error) { +// Interface lets you work with object metadata from any of the versioned or +// internal API objects. +type Interface interface { + Name() string + SetName(name string) + UID() string + SetUID(uid string) + APIVersion() string + SetAPIVersion(version string) + Kind() string + SetKind(kind string) + ResourceVersion() string + SetResourceVersion(version string) + SelfLink() string + SetSelfLink(selfLink string) +} + +// Accessor takes an arbitary object pointer and returns meta.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. +func Accessor(obj interface{}) (Interface, error) { v, err := conversion.EnforcePtr(obj) if err != nil { return nil, err } t := v.Type() - name := t.Name() if v.Kind() != reflect.Struct { - return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), name, v.Interface()) + return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), t, v.Interface()) } typeMeta := v.FieldByName("TypeMeta") if !typeMeta.IsValid() { - return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", name) + return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", t) } a := &genericAccessor{} - if err := findTypeMeta(typeMeta, a); err != nil { + if err := extractFromTypeMeta(typeMeta, a); err != nil { return nil, fmt.Errorf("unable to find type fields on %#v", typeMeta) } objectMeta := v.FieldByName("ObjectMeta") if objectMeta.IsValid() { // look for the ObjectMeta fields - if err := findObjectMeta(objectMeta, a); err != nil { + if err := extractFromObjectMeta(objectMeta, a); err != nil { return nil, fmt.Errorf("unable to find object fields on %#v", objectMeta) } } else { listMeta := v.FieldByName("ListMeta") if listMeta.IsValid() { // look for the ListMeta fields - if err := findListMeta(listMeta, a); err != nil { + if err := extractFromListMeta(listMeta, a); err != nil { return nil, fmt.Errorf("unable to find list fields on %#v", listMeta) } } else { // look for the older TypeMeta with all metadata - if err := findObjectMeta(typeMeta, a); err != nil { + if err := extractFromObjectMeta(typeMeta, a); err != nil { return nil, fmt.Errorf("unable to find object fields on %#v", typeMeta) } } @@ -82,7 +99,7 @@ func NewResourceVersioner() runtime.ResourceVersioner { type resourceAccessor struct{} func (v resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) { - accessor, err := FindAccessor(obj) + accessor, err := Accessor(obj) if err != nil { return "", err } @@ -90,7 +107,7 @@ func (v resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) { } func (v resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error { - accessor, err := FindAccessor(obj) + accessor, err := Accessor(obj) if err != nil { return err } @@ -99,7 +116,7 @@ func (v resourceAccessor) SetResourceVersion(obj runtime.Object, version string) } func (v resourceAccessor) Name(obj runtime.Object) (string, error) { - accessor, err := FindAccessor(obj) + accessor, err := Accessor(obj) if err != nil { return "", err } @@ -107,7 +124,7 @@ func (v resourceAccessor) Name(obj runtime.Object) (string, error) { } func (v resourceAccessor) SelfLink(obj runtime.Object) (string, error) { - accessor, err := FindAccessor(obj) + accessor, err := Accessor(obj) if err != nil { return "", err } @@ -115,7 +132,7 @@ func (v resourceAccessor) SelfLink(obj runtime.Object) (string, error) { } func (v resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error { - accessor, err := FindAccessor(obj) + accessor, err := Accessor(obj) if err != nil { return err } @@ -128,23 +145,6 @@ func NewSelfLinker() runtime.SelfLinker { return resourceAccessor{} } -// Accessor lets you work with object metadata from any of the versioned or -// internal APIruntime.Objects. -type Accessor interface { - Name() string - SetName(name string) - UID() string - SetUID(uid string) - APIVersion() string - SetAPIVersion(version string) - Kind() string - SetKind(kind string) - ResourceVersion() string - SetResourceVersion(version string) - SelfLink() string - SetSelfLink(selfLink string) -} - // genericAccessor contains pointers to strings that can modify an arbitrary // struct and implements the Accessor interface. type genericAccessor struct { @@ -241,8 +241,8 @@ func fieldPtr(v reflect.Value, fieldName string, dest interface{}) error { return fmt.Errorf("Couldn't assign/convert %v to %v", field.Type(), v.Type()) } -// findTypeMeta extracts pointers to version and kind fields from an object -func findTypeMeta(v reflect.Value, a *genericAccessor) error { +// extractFromTypeMeta extracts pointers to version and kind fields from an object +func extractFromTypeMeta(v reflect.Value, a *genericAccessor) error { if err := fieldPtr(v, "APIVersion", &a.apiVersion); err != nil { return err } @@ -252,8 +252,8 @@ func findTypeMeta(v reflect.Value, a *genericAccessor) error { return nil } -// findObjectMeta extracts pointers to metadata fields from an object -func findObjectMeta(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, "Name", &a.name); err != nil { return err } @@ -269,8 +269,8 @@ func findObjectMeta(v reflect.Value, a *genericAccessor) error { return nil } -// findObjectMeta extracts pointers to metadata fields from a list object -func findListMeta(v reflect.Value, a *genericAccessor) error { +// extractFromObjectMeta extracts pointers to metadata fields from a list object +func extractFromListMeta(v reflect.Value, a *genericAccessor) error { if err := fieldPtr(v, "ResourceVersion", &a.resourceVersion); err != nil { return err } diff --git a/pkg/api/meta/meta_test.go b/pkg/api/meta/meta_test.go index 094b231f015..1d7653e16fe 100644 --- a/pkg/api/meta/meta_test.go +++ b/pkg/api/meta/meta_test.go @@ -46,7 +46,7 @@ func TestGenericTypeMeta(t *testing.T) { SelfLink: "some/place/only/we/know", }, } - accessor, err := FindAccessor(&j) + accessor, err := Accessor(&j) if err != nil { t.Fatalf("new err: %v", err) } @@ -125,7 +125,7 @@ func TestGenericObjectMeta(t *testing.T) { SelfLink: "some/place/only/we/know", }, } - accessor, err := FindAccessor(&j) + accessor, err := Accessor(&j) if err != nil { t.Fatalf("new err: %v", err) } @@ -199,7 +199,7 @@ func TestGenericListMeta(t *testing.T) { SelfLink: "some/place/only/we/know", }, } - accessor, err := FindAccessor(&j) + accessor, err := Accessor(&j) if err != nil { t.Fatalf("new err: %v", err) } diff --git a/pkg/api/ref.go b/pkg/api/ref.go index 200fa34b557..c21533fe7fa 100644 --- a/pkg/api/ref.go +++ b/pkg/api/ref.go @@ -36,7 +36,7 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) { if obj == nil { return nil, ErrNilObject } - accessor, err := meta.FindAccessor(obj) + meta, err := meta.Accessor(obj) if err != nil { return nil, err } @@ -44,16 +44,16 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) { if err != nil { return nil, err } - version := versionFromSelfLink.FindStringSubmatch(accessor.SelfLink()) + version := versionFromSelfLink.FindStringSubmatch(meta.SelfLink()) if len(version) < 2 { - return nil, fmt.Errorf("unexpected self link format: %v", accessor.SelfLink()) + return nil, fmt.Errorf("unexpected self link format: %v", meta.SelfLink()) } return &ObjectReference{ Kind: kind, APIVersion: version[1], // TODO: correct Name and UID when TypeMeta makes a distinction - Name: accessor.Name(), - UID: accessor.UID(), - ResourceVersion: accessor.ResourceVersion(), + Name: meta.Name(), + UID: meta.UID(), + ResourceVersion: meta.ResourceVersion(), }, nil } diff --git a/pkg/api/serialization_test.go b/pkg/api/serialization_test.go index 7c242604dae..731e680a0f5 100644 --- a/pkg/api/serialization_test.go +++ b/pkg/api/serialization_test.go @@ -101,7 +101,7 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs( func runTest(t *testing.T, codec runtime.Codec, source runtime.Object) { name := reflect.TypeOf(source).Elem().Name() apiObjectFuzzer.Fuzz(source) - j, err := meta.FindAccessor(source) + j, err := meta.Accessor(source) if err != nil { t.Fatalf("Unexpected error %v for %#v", err, source) } @@ -160,7 +160,7 @@ func TestTypes(t *testing.T) { t.Errorf("Couldn't make a %v? %v", kind, err) continue } - if _, err := meta.FindAccessor(item); err != nil { + if _, err := meta.Accessor(item); err != nil { t.Logf("%s is not a TypeMeta and cannot be round tripped: %v", kind, err) continue } diff --git a/pkg/client/cache/reflector.go b/pkg/client/cache/reflector.go index d9036a716be..b360699a6ce 100644 --- a/pkg/client/cache/reflector.go +++ b/pkg/client/cache/reflector.go @@ -79,12 +79,12 @@ func (r *Reflector) listAndWatch() { glog.Errorf("Failed to list %v: %v", r.expectedType, err) return } - jsonBase, err := meta.FindAccessor(list) + meta, err := meta.Accessor(list) if err != nil { glog.Errorf("Unable to understand list result %#v", list) return } - resourceVersion = jsonBase.ResourceVersion() + resourceVersion = meta.ResourceVersion() items, err := runtime.ExtractList(list) if err != nil { glog.Errorf("Unable to understand list result %#v (%v)", list, err) @@ -113,11 +113,11 @@ func (r *Reflector) listAndWatch() { func (r *Reflector) syncWith(items []runtime.Object) error { found := map[string]interface{}{} for _, item := range items { - jsonBase, err := meta.FindAccessor(item) + meta, err := meta.Accessor(item) if err != nil { return fmt.Errorf("unexpected item in list: %v", err) } - found[jsonBase.Name()] = item + found[meta.Name()] = item } r.store.Replace(found) @@ -140,25 +140,25 @@ func (r *Reflector) watchHandler(w watch.Interface, resourceVersion *string) err glog.Errorf("expected type %v, but watch event object had type %v", e, a) continue } - jsonBase, err := meta.FindAccessor(event.Object) + meta, err := meta.Accessor(event.Object) if err != nil { glog.Errorf("unable to understand watch event %#v", event) continue } switch event.Type { case watch.Added: - r.store.Add(jsonBase.Name(), event.Object) + r.store.Add(meta.Name(), event.Object) case watch.Modified: - r.store.Update(jsonBase.Name(), event.Object) + r.store.Update(meta.Name(), event.Object) case watch.Deleted: // TODO: Will any consumers need access to the "last known // state", which is passed in event.Object? If so, may need // to change this. - r.store.Delete(jsonBase.Name()) + r.store.Delete(meta.Name()) default: glog.Errorf("unable to understand watch event %#v", event) } - *resourceVersion = jsonBase.ResourceVersion() + *resourceVersion = meta.ResourceVersion() eventCount++ } diff --git a/pkg/kubectl/modify.go b/pkg/kubectl/modify.go index c7420abc642..eeeda63cd1f 100644 --- a/pkg/kubectl/modify.go +++ b/pkg/kubectl/modify.go @@ -110,11 +110,11 @@ func doUpdate(c *client.RESTClient, resource string, obj runtime.Object) (string // Update the object we are trying to send to the server with the // correct resource version. - typeMeta, err := meta.FindAccessor(obj) + meta, err := meta.Accessor(obj) if err != nil { return "", err } - typeMeta.SetResourceVersion(version) + meta.SetResourceVersion(version) // Convert object with updated resourceVersion to data for PUT. data, err := c.Codec.Encode(obj) @@ -150,17 +150,17 @@ func doDelete(c *client.RESTClient, resource string, obj runtime.Object) (string } func getIDFromObj(obj runtime.Object) (string, error) { - typeMeta, err := meta.FindAccessor(obj) + meta, err := meta.Accessor(obj) if err != nil { return "", err } - return typeMeta.Name(), nil + return meta.Name(), nil } func getResourceVersionFromObj(obj runtime.Object) (string, error) { - typeMeta, err := meta.FindAccessor(obj) + meta, err := meta.Accessor(obj) if err != nil { return "", err } - return typeMeta.ResourceVersion(), nil + return meta.ResourceVersion(), nil }