diff --git a/cmd/kubecfg/kubecfg.go b/cmd/kubecfg/kubecfg.go index 65c7f05d85..87c96b13bf 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 a4570987f5..6509fbabfd 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 094b231f01..1d7653e16f 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 200fa34b55..c21533fe7f 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 7c242604da..731e680a0f 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 d9036a716b..b360699a6c 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 c7420abc64..eeeda63cd1 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 }