From 6ac7578699309e89224c443b7d5dba056ec2c33c Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Fri, 26 Sep 2014 17:29:46 -0700 Subject: [PATCH] Add GetReference() --- pkg/api/ref.go | 52 +++++++++++++++++++++++ pkg/api/ref_test.go | 95 +++++++++++++++++++++++++++++++++++++++++++ pkg/runtime/scheme.go | 7 ++++ 3 files changed, 154 insertions(+) create mode 100644 pkg/api/ref.go create mode 100644 pkg/api/ref_test.go diff --git a/pkg/api/ref.go b/pkg/api/ref.go new file mode 100644 index 0000000000..b420c5871c --- /dev/null +++ b/pkg/api/ref.go @@ -0,0 +1,52 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package api + +import ( + "fmt" + "regexp" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" +) + +var versionFromSelfLink = regexp.MustCompile("/api/([^/]*)/") + +// GetReference returns an ObjectReference which refers to the given +// object, or an error if the object doesn't follow the conventions +// that would allow this. +func GetReference(obj runtime.Object) (*ObjectReference, error) { + jsonBase, err := runtime.FindJSONBase(obj) + if err != nil { + return nil, err + } + _, kind, err := Scheme.ObjectVersionAndKind(obj) + if err != nil { + return nil, err + } + version := versionFromSelfLink.FindStringSubmatch(jsonBase.SelfLink()) + if len(version) < 2 { + return nil, fmt.Errorf("unexpected self link format: %v", jsonBase.SelfLink()) + } + return &ObjectReference{ + Kind: kind, + APIVersion: version[1], + // TODO: correct Name and UID when JSONBase makes a distinction + Name: jsonBase.ID(), + UID: jsonBase.ID(), + ResourceVersion: jsonBase.ResourceVersion(), + }, nil +} diff --git a/pkg/api/ref_test.go b/pkg/api/ref_test.go new file mode 100644 index 0000000000..3f22551705 --- /dev/null +++ b/pkg/api/ref_test.go @@ -0,0 +1,95 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package api + +import ( + "reflect" + "testing" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" +) + +type FakeAPIObject struct{} + +func (*FakeAPIObject) IsAnAPIObject() {} + +func TestGetReference(t *testing.T) { + table := map[string]struct { + obj runtime.Object + ref *ObjectReference + shouldErr bool + }{ + "pod": { + obj: &Pod{ + JSONBase: JSONBase{ + ID: "foo", + ResourceVersion: 42, + SelfLink: "/api/v1beta1/pods/foo", + }, + }, + ref: &ObjectReference{ + Kind: "Pod", + APIVersion: "v1beta1", + Name: "foo", + UID: "foo", + ResourceVersion: 42, + }, + }, + "serviceList": { + obj: &ServiceList{ + JSONBase: JSONBase{ + ID: "foo", + ResourceVersion: 42, + SelfLink: "/api/v1beta2/services", + }, + }, + ref: &ObjectReference{ + Kind: "ServiceList", + APIVersion: "v1beta2", + Name: "foo", + UID: "foo", + ResourceVersion: 42, + }, + }, + "badSelfLink": { + obj: &ServiceList{ + JSONBase: JSONBase{ + ID: "foo", + ResourceVersion: 42, + SelfLink: "v1beta2/services", + }, + }, + shouldErr: true, + }, + "error": { + obj: &FakeAPIObject{}, + ref: nil, + shouldErr: true, + }, + } + + for name, item := range table { + ref, err := GetReference(item.obj) + if e, a := item.shouldErr, (err != nil); e != a { + t.Errorf("%v: expected %v, got %v", name, e, a) + continue + } + if e, a := item.ref, ref; !reflect.DeepEqual(e, a) { + t.Errorf("%v: expected %#v, got %#v", name, e, a) + } + } +} diff --git a/pkg/runtime/scheme.go b/pkg/runtime/scheme.go index 4620e5a704..7ad8e6468a 100644 --- a/pkg/runtime/scheme.go +++ b/pkg/runtime/scheme.go @@ -198,10 +198,17 @@ func (s *Scheme) AddKnownTypeWithName(version, kind string, obj Object) { s.raw.AddKnownTypeWithName(version, kind, obj) } +// KnownTypes returns the types known for the given version. +// Return value must be treated as read-only. func (s *Scheme) KnownTypes(version string) map[string]reflect.Type { return s.raw.KnownTypes(version) } +// ObjectVersionAndKind returns the version and kind of the given Object. +func (s *Scheme) ObjectVersionAndKind(obj Object) (version, kind string, err error) { + return s.raw.ObjectVersionAndKind(obj) +} + // New returns a new API object of the given version ("" for internal // representation) and name, or an error if it hasn't been registered. func (s *Scheme) New(versionName, typeName string) (Object, error) {