Change runtime.Object signature

pull/6/head
Clayton Coleman 2015-12-07 22:01:12 -05:00
parent 114f6f76dc
commit 8f203a28f1
64 changed files with 831 additions and 364 deletions

View File

@ -39,5 +39,5 @@ func addKnownTypes() {
&unversioned.ListOptions{}) &unversioned.ListOptions{})
} }
func (*TestType) IsAnAPIObject() {} func (obj *TestType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*TestTypeList) IsAnAPIObject() {} func (obj *TestTypeList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -42,5 +42,5 @@ func addKnownTypes() {
&unversioned.ListOptions{}) &unversioned.ListOptions{})
} }
func (*TestType) IsAnAPIObject() {} func (obj *TestType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*TestTypeList) IsAnAPIObject() {} func (obj *TestTypeList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -22,6 +22,7 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api/unversioned"
etcdutil "k8s.io/kubernetes/pkg/storage/etcd/util" etcdutil "k8s.io/kubernetes/pkg/storage/etcd/util"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/watch" "k8s.io/kubernetes/pkg/watch"
@ -34,7 +35,7 @@ type Master string
// TODO(k8s): Either fix watch so this isn't necessary, or make this a real API Object. // TODO(k8s): Either fix watch so this isn't necessary, or make this a real API Object.
// TODO(k8s): when it becomes clear how this package will be used, move these declarations to // TODO(k8s): when it becomes clear how this package will be used, move these declarations to
// to the proper place. // to the proper place.
func (Master) IsAnAPIObject() {} func (obj Master) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
// NewEtcdMasterElector returns an implementation of election.MasterElector backed by etcd. // NewEtcdMasterElector returns an implementation of election.MasterElector backed by etcd.
func NewEtcdMasterElector(h *etcd.Client) MasterElector { func NewEtcdMasterElector(h *etcd.Client) MasterElector {

View File

@ -169,7 +169,7 @@ func Test_reasonForError(t *testing.T) {
type TestType struct{} type TestType struct{}
func (*TestType) IsAnAPIObject() {} func (obj *TestType) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
func TestFromObject(t *testing.T) { func TestFromObject(t *testing.T) {
table := []struct { table := []struct {

View File

@ -20,6 +20,7 @@ import (
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
) )
@ -60,3 +61,22 @@ func ListMetaFor(obj runtime.Object) (*unversioned.ListMeta, error) {
err = runtime.FieldPtr(v, "ListMeta", &meta) err = runtime.FieldPtr(v, "ListMeta", &meta)
return meta, err return meta, err
} }
// Namespace implements meta.Object for any object with an ObjectMeta typed field. Allows
// fast, direct access to metadata fields for API objects.
func (meta *ObjectMeta) GetNamespace() string { return meta.Namespace }
func (meta *ObjectMeta) SetNamespace(namespace string) { meta.Namespace = namespace }
func (meta *ObjectMeta) GetName() string { return meta.Name }
func (meta *ObjectMeta) SetName(name string) { meta.Name = name }
func (meta *ObjectMeta) GetGenerateName() string { return meta.GenerateName }
func (meta *ObjectMeta) SetGenerateName(generateName string) { meta.GenerateName = generateName }
func (meta *ObjectMeta) GetUID() types.UID { return meta.UID }
func (meta *ObjectMeta) SetUID(uid types.UID) { meta.UID = uid }
func (meta *ObjectMeta) GetResourceVersion() string { return meta.ResourceVersion }
func (meta *ObjectMeta) SetResourceVersion(version string) { meta.ResourceVersion = version }
func (meta *ObjectMeta) GetSelfLink() string { return meta.SelfLink }
func (meta *ObjectMeta) SetSelfLink(selfLink string) { meta.SelfLink = selfLink }
func (meta *ObjectMeta) GetLabels() map[string]string { return meta.Labels }
func (meta *ObjectMeta) SetLabels(labels map[string]string) { meta.Labels = labels }
func (meta *ObjectMeta) GetAnnotations() map[string]string { return meta.Annotations }
func (meta *ObjectMeta) SetAnnotations(annotations map[string]string) { meta.Annotations = annotations }

View File

@ -22,6 +22,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
@ -114,7 +115,9 @@ type fakePtrInterfaceList struct {
Items *[]runtime.Object Items *[]runtime.Object
} }
func (f fakePtrInterfaceList) IsAnAPIObject() {} func (obj fakePtrInterfaceList) GetObjectKind() unversioned.ObjectKind {
return unversioned.EmptyObjectKind
}
func TestExtractListOfInterfacePtrs(t *testing.T) { func TestExtractListOfInterfacePtrs(t *testing.T) {
pl := &fakePtrInterfaceList{ pl := &fakePtrInterfaceList{
@ -133,7 +136,9 @@ type fakePtrValueList struct {
Items []*api.Pod Items []*api.Pod
} }
func (f fakePtrValueList) IsAnAPIObject() {} func (obj fakePtrValueList) GetObjectKind() unversioned.ObjectKind {
return unversioned.EmptyObjectKind
}
func TestExtractListOfValuePtrs(t *testing.T) { func TestExtractListOfValuePtrs(t *testing.T) {
pl := &fakePtrValueList{ pl := &fakePtrValueList{

View File

@ -29,37 +29,48 @@ type VersionInterfaces struct {
MetadataAccessor MetadataAccessor
} }
// Interface lets you work with object and list metadata from any of the versioned or type ObjectMetaAccessor interface {
GetObjectMeta() Object
}
// Object lets you work with object metadata from any of the versioned or
// internal API objects. Attempting to set or retrieve a field on an object that does // 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 // not support that field (Name, UID, Namespace on lists) will be a no-op and return
// a default value. // a default value.
// TODO: rename to ObjectInterface when we clear up these interfaces. type Object interface {
type Interface interface { GetNamespace() string
TypeInterface
Namespace() string
SetNamespace(namespace string) SetNamespace(namespace string)
Name() string GetName() string
SetName(name string) SetName(name string)
GenerateName() string GetGenerateName() string
SetGenerateName(name string) SetGenerateName(name string)
UID() types.UID GetUID() types.UID
SetUID(uid types.UID) SetUID(uid types.UID)
ResourceVersion() string GetResourceVersion() string
SetResourceVersion(version string) SetResourceVersion(version string)
SelfLink() string GetSelfLink() string
SetSelfLink(selfLink string) SetSelfLink(selfLink string)
Labels() map[string]string GetLabels() map[string]string
SetLabels(labels map[string]string) SetLabels(labels map[string]string)
Annotations() map[string]string GetAnnotations() map[string]string
SetAnnotations(annotations map[string]string) SetAnnotations(annotations map[string]string)
} }
// TypeInterface exposes the type and APIVersion of versioned or internal API objects. // List lets you work with list metadata from any of the versioned or
type TypeInterface interface { // internal API objects. Attempting to set or retrieve a field on an object that does
APIVersion() string // not support that field will be a no-op and return a default value.
type List interface {
GetResourceVersion() string
SetResourceVersion(version string)
GetSelfLink() string
SetSelfLink(selfLink string)
}
// Type exposes the type and APIVersion of versioned or internal API objects.
type Type interface {
GetAPIVersion() string
SetAPIVersion(version string) SetAPIVersion(version string)
Kind() string GetKind() string
SetKind(kind string) SetKind(kind string)
} }

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
@ -29,8 +30,18 @@ import (
// obj must be a pointer to an API type. An error is returned if the minimum // 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 // required fields are missing. Fields that are not required return the default
// value and are a no-op if set. // value and are a no-op if set.
// TODO: add a fast path for *TypeMeta and *ObjectMeta for internal objects func Accessor(obj interface{}) (Object, error) {
func Accessor(obj interface{}) (Interface, error) { if oi, ok := obj.(ObjectMetaAccessor); ok {
if om := oi.GetObjectMeta(); om != nil {
return om, nil
}
}
// we may get passed an object that is directly portable to Object
if oi, ok := obj.(Object); ok {
return oi, nil
}
// legacy path for objects that do not implement Object and ObjectMetaAccessor via
// reflection - very slow code path.
v, err := conversion.EnforcePtr(obj) v, err := conversion.EnforcePtr(obj)
if err != nil { if err != nil {
return nil, err return nil, err
@ -79,7 +90,10 @@ func Accessor(obj interface{}) (Interface, error) {
// TODO: this interface is used to test code that does not have ObjectMeta or ListMeta // TODO: this interface is used to test code that does not have ObjectMeta or ListMeta
// in round tripping (objects which can use apiVersion/kind, but do not fit the Kube // in round tripping (objects which can use apiVersion/kind, but do not fit the Kube
// api conventions). // api conventions).
func TypeAccessor(obj interface{}) (TypeInterface, error) { func TypeAccessor(obj interface{}) (Type, error) {
if typed, ok := obj.(runtime.Object); ok {
return objectAccessor{typed}, nil
}
v, err := conversion.EnforcePtr(obj) v, err := conversion.EnforcePtr(obj)
if err != nil { if err != nil {
return nil, err return nil, err
@ -100,6 +114,46 @@ func TypeAccessor(obj interface{}) (TypeInterface, error) {
return a, nil return a, nil
} }
type objectAccessor struct {
runtime.Object
}
func (obj objectAccessor) GetKind() string {
if gvk := obj.GetObjectKind().GroupVersionKind(); gvk != nil {
return gvk.Kind
}
return ""
}
func (obj objectAccessor) SetKind(kind string) {
gvk := obj.GetObjectKind().GroupVersionKind()
if gvk == nil {
gvk = &unversioned.GroupVersionKind{}
}
gvk.Kind = kind
obj.GetObjectKind().SetGroupVersionKind(gvk)
}
func (obj objectAccessor) GetAPIVersion() string {
if gvk := obj.GetObjectKind().GroupVersionKind(); gvk != nil {
return gvk.GroupVersion().String()
}
return ""
}
func (obj objectAccessor) SetAPIVersion(version string) {
gvk := obj.GetObjectKind().GroupVersionKind()
if gvk == nil {
gvk = &unversioned.GroupVersionKind{}
}
gv, err := unversioned.ParseGroupVersion(version)
if err != nil {
gv = unversioned.GroupVersion{Version: version}
}
gvk.Group, gvk.Version = gv.Group, gv.Version
obj.GetObjectKind().SetGroupVersionKind(gvk)
}
// NewAccessor returns a MetadataAccessor that can retrieve // NewAccessor returns a MetadataAccessor that can retrieve
// or manipulate resource version on objects derived from core API // or manipulate resource version on objects derived from core API
// metadata concepts. // metadata concepts.
@ -111,36 +165,20 @@ func NewAccessor() MetadataAccessor {
type resourceAccessor struct{} type resourceAccessor struct{}
func (resourceAccessor) Kind(obj runtime.Object) (string, error) { func (resourceAccessor) Kind(obj runtime.Object) (string, error) {
accessor, err := Accessor(obj) return objectAccessor{obj}.GetKind(), nil
if err != nil {
return "", err
}
return accessor.Kind(), nil
} }
func (resourceAccessor) SetKind(obj runtime.Object, kind string) error { func (resourceAccessor) SetKind(obj runtime.Object, kind string) error {
accessor, err := Accessor(obj) objectAccessor{obj}.SetKind(kind)
if err != nil {
return err
}
accessor.SetKind(kind)
return nil return nil
} }
func (resourceAccessor) APIVersion(obj runtime.Object) (string, error) { func (resourceAccessor) APIVersion(obj runtime.Object) (string, error) {
accessor, err := Accessor(obj) return objectAccessor{obj}.GetAPIVersion(), nil
if err != nil {
return "", err
}
return accessor.APIVersion(), nil
} }
func (resourceAccessor) SetAPIVersion(obj runtime.Object, version string) error { func (resourceAccessor) SetAPIVersion(obj runtime.Object, version string) error {
accessor, err := Accessor(obj) objectAccessor{obj}.SetAPIVersion(version)
if err != nil {
return err
}
accessor.SetAPIVersion(version)
return nil return nil
} }
@ -149,7 +187,7 @@ func (resourceAccessor) Namespace(obj runtime.Object) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
return accessor.Namespace(), nil return accessor.GetNamespace(), nil
} }
func (resourceAccessor) SetNamespace(obj runtime.Object, namespace string) error { func (resourceAccessor) SetNamespace(obj runtime.Object, namespace string) error {
@ -166,7 +204,7 @@ func (resourceAccessor) Name(obj runtime.Object) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
return accessor.Name(), nil return accessor.GetName(), nil
} }
func (resourceAccessor) SetName(obj runtime.Object, name string) error { func (resourceAccessor) SetName(obj runtime.Object, name string) error {
@ -183,7 +221,7 @@ func (resourceAccessor) GenerateName(obj runtime.Object) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
return accessor.GenerateName(), nil return accessor.GetGenerateName(), nil
} }
func (resourceAccessor) SetGenerateName(obj runtime.Object, name string) error { func (resourceAccessor) SetGenerateName(obj runtime.Object, name string) error {
@ -200,7 +238,7 @@ func (resourceAccessor) UID(obj runtime.Object) (types.UID, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
return accessor.UID(), nil return accessor.GetUID(), nil
} }
func (resourceAccessor) SetUID(obj runtime.Object, uid types.UID) error { func (resourceAccessor) SetUID(obj runtime.Object, uid types.UID) error {
@ -217,7 +255,7 @@ func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
return accessor.SelfLink(), nil return accessor.GetSelfLink(), nil
} }
func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error { func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error {
@ -234,7 +272,7 @@ func (resourceAccessor) Labels(obj runtime.Object) (map[string]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return accessor.Labels(), nil return accessor.GetLabels(), nil
} }
func (resourceAccessor) SetLabels(obj runtime.Object, labels map[string]string) error { func (resourceAccessor) SetLabels(obj runtime.Object, labels map[string]string) error {
@ -251,7 +289,7 @@ func (resourceAccessor) Annotations(obj runtime.Object) (map[string]string, erro
if err != nil { if err != nil {
return nil, err return nil, err
} }
return accessor.Annotations(), nil return accessor.GetAnnotations(), nil
} }
func (resourceAccessor) SetAnnotations(obj runtime.Object, annotations map[string]string) error { func (resourceAccessor) SetAnnotations(obj runtime.Object, annotations map[string]string) error {
@ -268,7 +306,7 @@ func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
return accessor.ResourceVersion(), nil return accessor.GetResourceVersion(), nil
} }
func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error { func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error {
@ -295,7 +333,7 @@ type genericAccessor struct {
annotations *map[string]string annotations *map[string]string
} }
func (a genericAccessor) Namespace() string { func (a genericAccessor) GetNamespace() string {
if a.namespace == nil { if a.namespace == nil {
return "" return ""
} }
@ -309,7 +347,7 @@ func (a genericAccessor) SetNamespace(namespace string) {
*a.namespace = namespace *a.namespace = namespace
} }
func (a genericAccessor) Name() string { func (a genericAccessor) GetName() string {
if a.name == nil { if a.name == nil {
return "" return ""
} }
@ -323,7 +361,7 @@ func (a genericAccessor) SetName(name string) {
*a.name = name *a.name = name
} }
func (a genericAccessor) GenerateName() string { func (a genericAccessor) GetGenerateName() string {
if a.generateName == nil { if a.generateName == nil {
return "" return ""
} }
@ -337,7 +375,7 @@ func (a genericAccessor) SetGenerateName(generateName string) {
*a.generateName = generateName *a.generateName = generateName
} }
func (a genericAccessor) UID() types.UID { func (a genericAccessor) GetUID() types.UID {
if a.uid == nil { if a.uid == nil {
return "" return ""
} }
@ -351,7 +389,7 @@ func (a genericAccessor) SetUID(uid types.UID) {
*a.uid = uid *a.uid = uid
} }
func (a genericAccessor) APIVersion() string { func (a genericAccessor) GetAPIVersion() string {
return *a.apiVersion return *a.apiVersion
} }
@ -359,7 +397,7 @@ func (a genericAccessor) SetAPIVersion(version string) {
*a.apiVersion = version *a.apiVersion = version
} }
func (a genericAccessor) Kind() string { func (a genericAccessor) GetKind() string {
return *a.kind return *a.kind
} }
@ -367,7 +405,7 @@ func (a genericAccessor) SetKind(kind string) {
*a.kind = kind *a.kind = kind
} }
func (a genericAccessor) ResourceVersion() string { func (a genericAccessor) GetResourceVersion() string {
return *a.resourceVersion return *a.resourceVersion
} }
@ -375,7 +413,7 @@ func (a genericAccessor) SetResourceVersion(version string) {
*a.resourceVersion = version *a.resourceVersion = version
} }
func (a genericAccessor) SelfLink() string { func (a genericAccessor) GetSelfLink() string {
return *a.selfLink return *a.selfLink
} }
@ -383,7 +421,7 @@ func (a genericAccessor) SetSelfLink(selfLink string) {
*a.selfLink = selfLink *a.selfLink = selfLink
} }
func (a genericAccessor) Labels() map[string]string { func (a genericAccessor) GetLabels() map[string]string {
if a.labels == nil { if a.labels == nil {
return nil return nil
} }
@ -394,7 +432,7 @@ func (a genericAccessor) SetLabels(labels map[string]string) {
*a.labels = labels *a.labels = labels
} }
func (a genericAccessor) Annotations() map[string]string { func (a genericAccessor) GetAnnotations() map[string]string {
if a.annotations == nil { if a.annotations == nil {
return nil return nil
} }

View File

@ -14,16 +14,117 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package meta package meta_test
import ( import (
"reflect" "reflect"
"testing" "testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/types"
) )
func TestAPIObjectMeta(t *testing.T) {
j := &api.Pod{
TypeMeta: unversioned.TypeMeta{APIVersion: "/a", Kind: "b"},
ObjectMeta: api.ObjectMeta{
Namespace: "bar",
Name: "foo",
GenerateName: "prefix",
UID: "uid",
ResourceVersion: "1",
SelfLink: "some/place/only/we/know",
Labels: map[string]string{"foo": "bar"},
Annotations: map[string]string{"x": "y"},
},
}
var _ meta.Object = &j.ObjectMeta
var _ meta.ObjectMetaAccessor = j
accessor, err := meta.Accessor(j)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if accessor != meta.Object(&j.ObjectMeta) {
t.Fatalf("should have returned the same pointer: %#v %#v", accessor, j)
}
if e, a := "bar", accessor.GetNamespace(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "foo", accessor.GetName(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "prefix", accessor.GetGenerateName(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "uid", string(accessor.GetUID()); e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "1", accessor.GetResourceVersion(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "some/place/only/we/know", accessor.GetSelfLink(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
typeAccessor, err := meta.TypeAccessor(j)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if e, a := "/a", typeAccessor.GetAPIVersion(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "b", typeAccessor.GetKind(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
accessor.SetNamespace("baz")
accessor.SetName("bar")
accessor.SetGenerateName("generate")
accessor.SetUID("other")
typeAccessor.SetAPIVersion("c")
typeAccessor.SetKind("d")
accessor.SetResourceVersion("2")
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)
}
if e, a := "generate", j.GenerateName; e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := types.UID("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)
}
typeAccessor.SetAPIVersion("d")
typeAccessor.SetKind("e")
if e, a := "/d", j.APIVersion; e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := "e", j.Kind; e != a {
t.Errorf("expected %v, got %v", e, a)
}
}
func TestGenericTypeMeta(t *testing.T) { func TestGenericTypeMeta(t *testing.T) {
type TypeMeta struct { type TypeMeta struct {
Kind string `json:"kind,omitempty"` Kind string `json:"kind,omitempty"`
@ -55,43 +156,37 @@ func TestGenericTypeMeta(t *testing.T) {
Annotations: map[string]string{"x": "y"}, Annotations: map[string]string{"x": "y"},
}, },
} }
accessor, err := Accessor(&j) accessor, err := meta.Accessor(&j)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
if e, a := "bar", accessor.Namespace(); e != a { if e, a := "bar", accessor.GetNamespace(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "foo", accessor.Name(); e != a { if e, a := "foo", accessor.GetName(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "prefix", accessor.GenerateName(); e != a { if e, a := "prefix", accessor.GetGenerateName(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "uid", string(accessor.UID()); e != a { if e, a := "uid", string(accessor.GetUID()); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "a", accessor.APIVersion(); e != a { if e, a := "1", accessor.GetResourceVersion(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "b", accessor.Kind(); e != a { if e, a := "some/place/only/we/know", accessor.GetSelfLink(); 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) t.Errorf("expected %v, got %v", e, a)
} }
typeAccessor, err := TypeAccessor(&j) typeAccessor, err := meta.TypeAccessor(&j)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
if e, a := "a", accessor.APIVersion(); e != a { if e, a := "a", typeAccessor.GetAPIVersion(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "b", accessor.Kind(); e != a { if e, a := "b", typeAccessor.GetKind(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
@ -99,8 +194,8 @@ func TestGenericTypeMeta(t *testing.T) {
accessor.SetName("bar") accessor.SetName("bar")
accessor.SetGenerateName("generate") accessor.SetGenerateName("generate")
accessor.SetUID("other") accessor.SetUID("other")
accessor.SetAPIVersion("c") typeAccessor.SetAPIVersion("c")
accessor.SetKind("d") typeAccessor.SetKind("d")
accessor.SetResourceVersion("2") accessor.SetResourceVersion("2")
accessor.SetSelfLink("google.com") accessor.SetSelfLink("google.com")
@ -157,7 +252,13 @@ type InternalObject struct {
TypeMeta InternalTypeMeta `json:",inline"` TypeMeta InternalTypeMeta `json:",inline"`
} }
func (*InternalObject) IsAnAPIObject() {} func (obj *InternalObject) GetObjectKind() unversioned.ObjectKind { return obj }
func (obj *InternalObject) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *InternalObject) GroupVersionKind() *unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind(obj.TypeMeta.APIVersion, obj.TypeMeta.Kind)
}
func TestGenericTypeMetaAccessor(t *testing.T) { func TestGenericTypeMetaAccessor(t *testing.T) {
j := &InternalObject{ j := &InternalObject{
@ -166,7 +267,7 @@ func TestGenericTypeMetaAccessor(t *testing.T) {
Name: "foo", Name: "foo",
GenerateName: "prefix", GenerateName: "prefix",
UID: "uid", UID: "uid",
APIVersion: "a", APIVersion: "/a",
Kind: "b", Kind: "b",
ResourceVersion: "1", ResourceVersion: "1",
SelfLink: "some/place/only/we/know", SelfLink: "some/place/only/we/know",
@ -174,7 +275,7 @@ func TestGenericTypeMetaAccessor(t *testing.T) {
Annotations: map[string]string{"x": "y"}, Annotations: map[string]string{"x": "y"},
}, },
} }
accessor := NewAccessor() accessor := meta.NewAccessor()
namespace, err := accessor.Namespace(j) namespace, err := accessor.Namespace(j)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -207,7 +308,7 @@ func TestGenericTypeMetaAccessor(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if e, a := "a", apiVersion; e != a { if e, a := "/a", apiVersion; e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
kind, err := accessor.Kind(j) kind, err := accessor.Kind(j)
@ -291,7 +392,7 @@ func TestGenericTypeMetaAccessor(t *testing.T) {
if e, a := "other", j.TypeMeta.UID; e != a { if e, a := "other", j.TypeMeta.UID; e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "c", j.TypeMeta.APIVersion; e != a { if e, a := "/c", j.TypeMeta.APIVersion; e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "d", j.TypeMeta.Kind; e != a { if e, a := "d", j.TypeMeta.Kind; e != a {
@ -347,38 +448,43 @@ func TestGenericObjectMeta(t *testing.T) {
Annotations: map[string]string{"a": "b"}, Annotations: map[string]string{"a": "b"},
}, },
} }
accessor, err := Accessor(&j) accessor, err := meta.Accessor(&j)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
if e, a := "bar", accessor.Namespace(); e != a { if e, a := "bar", accessor.GetNamespace(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "foo", accessor.Name(); e != a { if e, a := "foo", accessor.GetName(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "prefix", accessor.GenerateName(); e != a { if e, a := "prefix", accessor.GetGenerateName(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "uid", string(accessor.UID()); e != a { if e, a := "uid", string(accessor.GetUID()); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "a", accessor.APIVersion(); e != a { if e, a := "1", accessor.GetResourceVersion(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "b", accessor.Kind(); e != a { if e, a := "some/place/only/we/know", accessor.GetSelfLink(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "1", accessor.ResourceVersion(); e != a { if e, a := 1, len(accessor.GetLabels()); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "some/place/only/we/know", accessor.SelfLink(); e != a { if e, a := 1, len(accessor.GetAnnotations()); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := 1, len(accessor.Labels()); e != a {
typeAccessor, err := meta.TypeAccessor(&j)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if e, a := "a", typeAccessor.GetAPIVersion(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := 1, len(accessor.Annotations()); e != a { if e, a := "b", typeAccessor.GetKind(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
@ -386,8 +492,8 @@ func TestGenericObjectMeta(t *testing.T) {
accessor.SetName("bar") accessor.SetName("bar")
accessor.SetGenerateName("generate") accessor.SetGenerateName("generate")
accessor.SetUID("other") accessor.SetUID("other")
accessor.SetAPIVersion("c") typeAccessor.SetAPIVersion("c")
accessor.SetKind("d") typeAccessor.SetKind("d")
accessor.SetResourceVersion("2") accessor.SetResourceVersion("2")
accessor.SetSelfLink("google.com") accessor.SetSelfLink("google.com")
accessor.SetLabels(map[string]string{"other": "label"}) accessor.SetLabels(map[string]string{"other": "label"})
@ -449,33 +555,38 @@ func TestGenericListMeta(t *testing.T) {
SelfLink: "some/place/only/we/know", SelfLink: "some/place/only/we/know",
}, },
} }
accessor, err := Accessor(&j) accessor, err := meta.Accessor(&j)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
if e, a := "", accessor.Name(); e != a { if e, a := "", accessor.GetName(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "", string(accessor.UID()); e != a { if e, a := "", string(accessor.GetUID()); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "a", accessor.APIVersion(); e != a { if e, a := "1", accessor.GetResourceVersion(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "b", accessor.Kind(); e != a { if e, a := "some/place/only/we/know", accessor.GetSelfLink(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "1", accessor.ResourceVersion(); e != a {
typeAccessor, err := meta.TypeAccessor(&j)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if e, a := "a", typeAccessor.GetAPIVersion(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "some/place/only/we/know", accessor.SelfLink(); e != a { if e, a := "b", typeAccessor.GetKind(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
accessor.SetName("bar") accessor.SetName("bar")
accessor.SetUID("other") accessor.SetUID("other")
accessor.SetAPIVersion("c") typeAccessor.SetAPIVersion("c")
accessor.SetKind("d") typeAccessor.SetKind("d")
accessor.SetResourceVersion("2") accessor.SetResourceVersion("2")
accessor.SetSelfLink("google.com") accessor.SetSelfLink("google.com")
@ -498,12 +609,19 @@ type MyAPIObject struct {
TypeMeta InternalTypeMeta `json:",inline"` TypeMeta InternalTypeMeta `json:",inline"`
} }
func (*MyAPIObject) IsAnAPIObject() {} func (obj *MyAPIObject) GetObjectKind() unversioned.ObjectKind { return obj }
func (obj *MyAPIObject) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
type MyIncorrectlyMarkedAsAPIObject struct { obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *MyAPIObject) GroupVersionKind() *unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind(obj.TypeMeta.APIVersion, obj.TypeMeta.Kind)
} }
func (*MyIncorrectlyMarkedAsAPIObject) IsAnAPIObject() {} type MyIncorrectlyMarkedAsAPIObject struct{}
func (obj *MyIncorrectlyMarkedAsAPIObject) GetObjectKind() unversioned.ObjectKind {
return unversioned.EmptyObjectKind
}
func TestResourceVersionerOfAPI(t *testing.T) { func TestResourceVersionerOfAPI(t *testing.T) {
type T struct { type T struct {
@ -515,7 +633,7 @@ func TestResourceVersionerOfAPI(t *testing.T) {
"api object with version": {&MyAPIObject{TypeMeta: InternalTypeMeta{ResourceVersion: "1"}}, "1"}, "api object with version": {&MyAPIObject{TypeMeta: InternalTypeMeta{ResourceVersion: "1"}}, "1"},
"pointer to api object with version": {&MyAPIObject{TypeMeta: InternalTypeMeta{ResourceVersion: "1"}}, "1"}, "pointer to api object with version": {&MyAPIObject{TypeMeta: InternalTypeMeta{ResourceVersion: "1"}}, "1"},
} }
versioning := NewAccessor() versioning := meta.NewAccessor()
for key, testCase := range testCases { for key, testCase := range testCases {
actual, err := versioning.ResourceVersion(testCase.Object) actual, err := versioning.ResourceVersion(testCase.Object)
if err != nil { if err != nil {
@ -578,7 +696,7 @@ func TestTypeMetaSelfLinker(t *testing.T) {
}, },
} }
linker := runtime.SelfLinker(NewAccessor()) linker := runtime.SelfLinker(meta.NewAccessor())
for name, item := range table { for name, item := range table {
got, err := linker.SelfLink(item.obj) got, err := linker.SelfLink(item.obj)
if e, a := item.succeed, err == nil; e != a { if e, a := item.succeed, err == nil; e != a {
@ -603,3 +721,58 @@ func TestTypeMetaSelfLinker(t *testing.T) {
} }
} }
} }
// BenchmarkAccessorSetFastPath shows the interface fast path
func BenchmarkAccessorSetFastPath(b *testing.B) {
obj := &api.Pod{
TypeMeta: unversioned.TypeMeta{APIVersion: "/a", Kind: "b"},
ObjectMeta: api.ObjectMeta{
Namespace: "bar",
Name: "foo",
GenerateName: "prefix",
UID: "uid",
ResourceVersion: "1",
SelfLink: "some/place/only/we/know",
Labels: map[string]string{"foo": "bar"},
Annotations: map[string]string{"x": "y"},
},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
acc, err := meta.Accessor(obj)
if err != nil {
b.Fatal(err)
}
acc.SetNamespace("something")
}
b.StopTimer()
}
// BenchmarkAccessorSetReflection provides a baseline for accessor performance
func BenchmarkAccessorSetReflection(b *testing.B) {
obj := &InternalObject{
InternalTypeMeta{
Namespace: "bar",
Name: "foo",
GenerateName: "prefix",
UID: "uid",
APIVersion: "/a",
Kind: "b",
ResourceVersion: "1",
SelfLink: "some/place/only/we/know",
Labels: map[string]string{"foo": "bar"},
Annotations: map[string]string{"x": "y"},
},
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
acc, err := meta.Accessor(obj)
if err != nil {
b.Fatal(err)
}
acc.SetNamespace("something")
}
b.StopTimer()
}

View File

@ -20,8 +20,11 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
) )
var _ meta.Object = &api.ObjectMeta{}
// TestFillObjectMetaSystemFields validates that system populated fields are set on an object // TestFillObjectMetaSystemFields validates that system populated fields are set on an object
func TestFillObjectMetaSystemFields(t *testing.T) { func TestFillObjectMetaSystemFields(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()

View File

@ -23,6 +23,7 @@ import (
"strings" "strings"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
@ -49,10 +50,16 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) {
return nil, err return nil, err
} }
gvk := obj.GetObjectKind().GroupVersionKind()
// if the object referenced is actually persisted, we can just get kind from meta // if the object referenced is actually persisted, we can just get kind from meta
// if we are building an object reference to something not yet persisted, we should fallback to scheme // if we are building an object reference to something not yet persisted, we should fallback to scheme
kind := meta.Kind() var kind string
if kind == "" { if gvk != nil {
kind = gvk.Kind
}
if len(kind) == 0 {
// TODO: this is wrong
gvk, err := Scheme.ObjectKind(obj) gvk, err := Scheme.ObjectKind(obj)
if err != nil { if err != nil {
return nil, err return nil, err
@ -61,32 +68,34 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) {
} }
// if the object referenced is actually persisted, we can also get version from meta // if the object referenced is actually persisted, we can also get version from meta
version := meta.APIVersion() var version string
if version == "" { if gvk != nil {
selfLink := meta.SelfLink() version = gvk.GroupVersion().String()
if selfLink == "" { }
if len(version) == 0 {
selfLink := meta.GetSelfLink()
if len(selfLink) == 0 {
return nil, ErrNoSelfLink return nil, ErrNoSelfLink
} else {
selfLinkUrl, err := url.Parse(selfLink)
if err != nil {
return nil, err
}
// example paths: /<prefix>/<version>/*
parts := strings.Split(selfLinkUrl.Path, "/")
if len(parts) < 3 {
return nil, fmt.Errorf("unexpected self link format: '%v'; got version '%v'", selfLink, version)
}
version = parts[2]
} }
selfLinkUrl, err := url.Parse(selfLink)
if err != nil {
return nil, err
}
// example paths: /<prefix>/<version>/*
parts := strings.Split(selfLinkUrl.Path, "/")
if len(parts) < 3 {
return nil, fmt.Errorf("unexpected self link format: '%v'; got version '%v'", selfLink, version)
}
version = parts[2]
} }
return &ObjectReference{ return &ObjectReference{
Kind: kind, Kind: kind,
APIVersion: version, APIVersion: version,
Name: meta.Name(), Name: meta.GetName(),
Namespace: meta.Namespace(), Namespace: meta.GetNamespace(),
UID: meta.UID(), UID: meta.GetUID(),
ResourceVersion: meta.ResourceVersion(), ResourceVersion: meta.GetResourceVersion(),
}, nil }, nil
} }
@ -102,4 +111,9 @@ func GetPartialReference(obj runtime.Object, fieldPath string) (*ObjectReference
// IsAnAPIObject allows clients to preemptively get a reference to an API object and pass it to places that // IsAnAPIObject allows clients to preemptively get a reference to an API object and pass it to places that
// intend only to get a reference to that object. This simplifies the event recording interface. // intend only to get a reference to that object. This simplifies the event recording interface.
func (*ObjectReference) IsAnAPIObject() {} func (obj *ObjectReference) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *ObjectReference) GroupVersionKind() *unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}

View File

@ -26,14 +26,14 @@ import (
type FakeAPIObject struct{} type FakeAPIObject struct{}
func (*FakeAPIObject) IsAnAPIObject() {} func (obj *FakeAPIObject) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
type ExtensionAPIObject struct { type ExtensionAPIObject struct {
unversioned.TypeMeta unversioned.TypeMeta
ObjectMeta ObjectMeta
} }
func (*ExtensionAPIObject) IsAnAPIObject() {} func (obj *ExtensionAPIObject) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func TestGetReference(t *testing.T) { func TestGetReference(t *testing.T) {
table := map[string]struct { table := map[string]struct {

View File

@ -17,6 +17,7 @@ limitations under the License.
package api package api
import ( import (
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
@ -94,44 +95,63 @@ func init() {
Scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.APIResourceList{}) Scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.APIResourceList{})
} }
func (*Pod) IsAnAPIObject() {} func (obj *Pod) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*PodList) IsAnAPIObject() {} func (obj *Pod) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodStatusResult) IsAnAPIObject() {} func (obj *PodList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodTemplate) IsAnAPIObject() {} func (obj *PodStatusResult) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*PodTemplateList) IsAnAPIObject() {} func (obj *PodStatusResult) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ReplicationController) IsAnAPIObject() {} func (obj *PodTemplate) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*ReplicationControllerList) IsAnAPIObject() {} func (obj *PodTemplate) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Service) IsAnAPIObject() {} func (obj *PodTemplateList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ServiceList) IsAnAPIObject() {} func (obj *ReplicationController) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*Endpoints) IsAnAPIObject() {} func (obj *ReplicationController) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*EndpointsList) IsAnAPIObject() {} func (obj *ReplicationControllerList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Node) IsAnAPIObject() {} func (obj *Service) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*NodeList) IsAnAPIObject() {} func (obj *Service) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Binding) IsAnAPIObject() {} func (obj *ServiceList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Event) IsAnAPIObject() {} func (obj *Endpoints) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*EventList) IsAnAPIObject() {} func (obj *Endpoints) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*List) IsAnAPIObject() {} func (obj *EndpointsList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*LimitRange) IsAnAPIObject() {} func (obj *Node) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*LimitRangeList) IsAnAPIObject() {} func (obj *Node) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ResourceQuota) IsAnAPIObject() {} func (obj *NodeList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ResourceQuotaList) IsAnAPIObject() {} func (obj *Binding) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*Namespace) IsAnAPIObject() {} func (obj *Binding) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*NamespaceList) IsAnAPIObject() {} func (obj *Event) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*ServiceAccount) IsAnAPIObject() {} func (obj *Event) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ServiceAccountList) IsAnAPIObject() {} func (obj *EventList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Secret) IsAnAPIObject() {} func (obj *List) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*SecretList) IsAnAPIObject() {} func (obj *ListOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PersistentVolume) IsAnAPIObject() {} func (obj *LimitRange) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*PersistentVolumeList) IsAnAPIObject() {} func (obj *LimitRange) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PersistentVolumeClaim) IsAnAPIObject() {} func (obj *LimitRangeList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PersistentVolumeClaimList) IsAnAPIObject() {} func (obj *ResourceQuota) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*DeleteOptions) IsAnAPIObject() {} func (obj *ResourceQuota) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ListOptions) IsAnAPIObject() {} func (obj *ResourceQuotaList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodAttachOptions) IsAnAPIObject() {} func (obj *Namespace) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*PodLogOptions) IsAnAPIObject() {} func (obj *Namespace) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodExecOptions) IsAnAPIObject() {} func (obj *NamespaceList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodProxyOptions) IsAnAPIObject() {} func (obj *ServiceAccount) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*ComponentStatus) IsAnAPIObject() {} func (obj *ServiceAccount) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ComponentStatusList) IsAnAPIObject() {} func (obj *ServiceAccountList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*SerializedReference) IsAnAPIObject() {} func (obj *Secret) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (*RangeAllocation) IsAnAPIObject() {} func (obj *Secret) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *SecretList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *PersistentVolume) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (obj *PersistentVolume) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *PersistentVolumeList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *PersistentVolumeClaim) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (obj *PersistentVolumeClaim) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *PersistentVolumeClaimList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *DeleteOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *PodAttachOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *PodLogOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *PodExecOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *PodProxyOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *ComponentStatus) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (obj *ComponentStatus) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *ComponentStatusList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *SerializedReference) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *RangeAllocation) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
func (obj *RangeAllocation) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *ObjectReference) GetObjectKind() unversioned.ObjectKind { return obj }

View File

@ -274,5 +274,4 @@ type ConnectRequest struct {
ResourcePath string ResourcePath string
} }
// IsAnAPIObject makes ConnectRequest a runtime.Object func (obj *ConnectRequest) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
func (*ConnectRequest) IsAnAPIObject() {}

View File

@ -198,3 +198,48 @@ func (gv *GroupVersion) UnmarshalJSON(value []byte) error {
func (gv *GroupVersion) UnmarshalText(value []byte) error { func (gv *GroupVersion) UnmarshalText(value []byte) error {
return gv.unmarshal(value) return gv.unmarshal(value)
} }
// ToAPIVersionAndKind is a convenience method for satisfying runtime.Object on types that
// do not use TypeMeta.
func (gvk *GroupVersionKind) ToAPIVersionAndKind() (string, string) {
if gvk == nil {
return "", ""
}
return gvk.GroupVersion().String(), gvk.Kind
}
// FromAPIVersionAndKind returns a GVK representing the provided fields for types that
// do not use TypeMeta. This method exists to support test types and legacy serializations
// that have a distinct group and kind.
// TODO: further reduce usage of this method.
func FromAPIVersionAndKind(apiVersion, kind string) *GroupVersionKind {
if gv, err := ParseGroupVersion(apiVersion); err == nil {
return &GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: kind}
}
return &GroupVersionKind{Kind: kind}
}
// All objects that are serialized from a Scheme encode their type information. This interface is used
// by serialization to set type information from the Scheme onto the serialized version of an object.
// For objects that cannot be serialized or have unique requirements, this interface may be a no-op.
// TODO: this belongs in pkg/runtime, move unversioned.GVK into runtime.
type ObjectKind interface {
// SetGroupVersionKind sets or clears the intended serialized kind of an object. Passing kind nil
// should clear the current setting.
SetGroupVersionKind(kind *GroupVersionKind)
// GroupVersionKind returns the stored group, version, and kind of an object, or nil if the object does
// not expose or provide these fields.
GroupVersionKind() *GroupVersionKind
}
// EmptyObjectKind implements the ObjectKind interface as a noop
// TODO: this belongs in pkg/runtime, move unversioned.GVK into runtime.
var EmptyObjectKind = emptyObjectKind{}
type emptyObjectKind struct{}
// SetGroupVersionKind implements the ObjectKind interface
func (emptyObjectKind) SetGroupVersionKind(gvk *GroupVersionKind) {}
// GroupVersionKind implements the ObjectKind interface
func (emptyObjectKind) GroupVersionKind() *GroupVersionKind { return nil }

View File

@ -24,4 +24,19 @@ func Kind(kind string) GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind() return SchemeGroupVersion.WithKind(kind).GroupKind()
} }
// TODO this doesn't actually register them right now due to cycles. // SetGroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta
func (obj *TypeMeta) SetGroupVersionKind(gvk *GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
// GroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta
func (obj *TypeMeta) GroupVersionKind() *GroupVersionKind {
return FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
func (obj *ListOptions) GetObjectKind() ObjectKind { return &obj.TypeMeta }
func (obj *Status) GetObjectKind() ObjectKind { return &obj.TypeMeta }
func (obj *APIVersions) GetObjectKind() ObjectKind { return &obj.TypeMeta }
func (obj *APIGroupList) GetObjectKind() ObjectKind { return &obj.TypeMeta }
func (obj *APIGroup) GetObjectKind() ObjectKind { return &obj.TypeMeta }
func (obj *APIResourceList) GetObjectKind() ObjectKind { return &obj.TypeMeta }

View File

@ -302,13 +302,6 @@ const (
CauseTypeUnexpectedServerResponse CauseType = "UnexpectedServerResponse" CauseTypeUnexpectedServerResponse CauseType = "UnexpectedServerResponse"
) )
func (*ListOptions) IsAnAPIObject() {}
func (*Status) IsAnAPIObject() {}
func (*APIVersions) IsAnAPIObject() {}
func (*APIGroupList) IsAnAPIObject() {}
func (*APIGroup) IsAnAPIObject() {}
func (*APIResourceList) IsAnAPIObject() {}
// APIVersions lists the versions that are available, to allow clients to // APIVersions lists the versions that are available, to allow clients to
// discover the API at /api, which is the root path of the legacy v1 API. // discover the API at /api, which is the root path of the legacy v1 API.
// //

View File

@ -94,44 +94,44 @@ func addKnownTypes() {
api.Scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.Status{}) api.Scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.Status{})
} }
func (*Pod) IsAnAPIObject() {} func (obj *Pod) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodList) IsAnAPIObject() {} func (obj *PodList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodStatusResult) IsAnAPIObject() {} func (obj *PodStatusResult) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodTemplate) IsAnAPIObject() {} func (obj *PodTemplate) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodTemplateList) IsAnAPIObject() {} func (obj *PodTemplateList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ReplicationController) IsAnAPIObject() {} func (obj *ReplicationController) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ReplicationControllerList) IsAnAPIObject() {} func (obj *ReplicationControllerList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Service) IsAnAPIObject() {} func (obj *Service) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ServiceList) IsAnAPIObject() {} func (obj *ServiceList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Endpoints) IsAnAPIObject() {} func (obj *Endpoints) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*EndpointsList) IsAnAPIObject() {} func (obj *EndpointsList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Node) IsAnAPIObject() {} func (obj *Node) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*NodeList) IsAnAPIObject() {} func (obj *NodeList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Binding) IsAnAPIObject() {} func (obj *Binding) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Event) IsAnAPIObject() {} func (obj *Event) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*EventList) IsAnAPIObject() {} func (obj *EventList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*List) IsAnAPIObject() {} func (obj *List) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*LimitRange) IsAnAPIObject() {} func (obj *LimitRange) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*LimitRangeList) IsAnAPIObject() {} func (obj *LimitRangeList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ResourceQuota) IsAnAPIObject() {} func (obj *ResourceQuota) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ResourceQuotaList) IsAnAPIObject() {} func (obj *ResourceQuotaList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Namespace) IsAnAPIObject() {} func (obj *Namespace) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*NamespaceList) IsAnAPIObject() {} func (obj *NamespaceList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Secret) IsAnAPIObject() {} func (obj *Secret) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*SecretList) IsAnAPIObject() {} func (obj *SecretList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ServiceAccount) IsAnAPIObject() {} func (obj *ServiceAccount) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ServiceAccountList) IsAnAPIObject() {} func (obj *ServiceAccountList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PersistentVolume) IsAnAPIObject() {} func (obj *PersistentVolume) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PersistentVolumeList) IsAnAPIObject() {} func (obj *PersistentVolumeList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PersistentVolumeClaim) IsAnAPIObject() {} func (obj *PersistentVolumeClaim) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PersistentVolumeClaimList) IsAnAPIObject() {} func (obj *PersistentVolumeClaimList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*DeleteOptions) IsAnAPIObject() {} func (obj *DeleteOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ListOptions) IsAnAPIObject() {} func (obj *ListOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodAttachOptions) IsAnAPIObject() {} func (obj *PodAttachOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodLogOptions) IsAnAPIObject() {} func (obj *PodLogOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodExecOptions) IsAnAPIObject() {} func (obj *PodExecOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*PodProxyOptions) IsAnAPIObject() {} func (obj *PodProxyOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ComponentStatus) IsAnAPIObject() {} func (obj *ComponentStatus) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ComponentStatusList) IsAnAPIObject() {} func (obj *ComponentStatusList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*SerializedReference) IsAnAPIObject() {} func (obj *SerializedReference) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*RangeAllocation) IsAnAPIObject() {} func (obj *RangeAllocation) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -34,4 +34,4 @@ func init() {
) )
} }
func (*Policy) IsAnAPIObject() {} func (obj *Policy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -34,4 +34,4 @@ func init() {
) )
} }
func (*Policy) IsAnAPIObject() {} func (obj *Policy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -34,4 +34,4 @@ func init() {
) )
} }
func (*Policy) IsAnAPIObject() {} func (obj *Policy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -48,4 +48,4 @@ func addKnownTypes() {
) )
} }
func (_ *KubeProxyConfiguration) IsAnAPIObject() {} func (obj *KubeProxyConfiguration) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -41,4 +41,4 @@ func addKnownTypes() {
) )
} }
func (_ *KubeProxyConfiguration) IsAnAPIObject() {} func (obj *KubeProxyConfiguration) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -68,21 +68,21 @@ func addKnownTypes() {
) )
} }
func (*ClusterAutoscaler) IsAnAPIObject() {} func (obj *ClusterAutoscaler) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ClusterAutoscalerList) IsAnAPIObject() {} func (obj *ClusterAutoscalerList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Deployment) IsAnAPIObject() {} func (obj *Deployment) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*DeploymentList) IsAnAPIObject() {} func (obj *DeploymentList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*HorizontalPodAutoscaler) IsAnAPIObject() {} func (obj *HorizontalPodAutoscaler) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*HorizontalPodAutoscalerList) IsAnAPIObject() {} func (obj *HorizontalPodAutoscalerList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Job) IsAnAPIObject() {} func (obj *Job) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*JobList) IsAnAPIObject() {} func (obj *JobList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ReplicationControllerDummy) IsAnAPIObject() {} func (obj *ReplicationControllerDummy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Scale) IsAnAPIObject() {} func (obj *Scale) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ThirdPartyResource) IsAnAPIObject() {} func (obj *ThirdPartyResource) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ThirdPartyResourceList) IsAnAPIObject() {} func (obj *ThirdPartyResourceList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*DaemonSet) IsAnAPIObject() {} func (obj *DaemonSet) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*DaemonSetList) IsAnAPIObject() {} func (obj *DaemonSetList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ThirdPartyResourceData) IsAnAPIObject() {} func (obj *ThirdPartyResourceData) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ThirdPartyResourceDataList) IsAnAPIObject() {} func (obj *ThirdPartyResourceDataList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Ingress) IsAnAPIObject() {} func (obj *Ingress) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*IngressList) IsAnAPIObject() {} func (obj *IngressList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -61,22 +61,22 @@ func addKnownTypes() {
) )
} }
func (*ClusterAutoscaler) IsAnAPIObject() {} func (obj *ClusterAutoscaler) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ClusterAutoscalerList) IsAnAPIObject() {} func (obj *ClusterAutoscalerList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Deployment) IsAnAPIObject() {} func (obj *Deployment) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*DeploymentList) IsAnAPIObject() {} func (obj *DeploymentList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*HorizontalPodAutoscaler) IsAnAPIObject() {} func (obj *HorizontalPodAutoscaler) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*HorizontalPodAutoscalerList) IsAnAPIObject() {} func (obj *HorizontalPodAutoscalerList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Job) IsAnAPIObject() {} func (obj *Job) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*JobList) IsAnAPIObject() {} func (obj *JobList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ReplicationControllerDummy) IsAnAPIObject() {} func (obj *ReplicationControllerDummy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Scale) IsAnAPIObject() {} func (obj *Scale) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ThirdPartyResource) IsAnAPIObject() {} func (obj *ThirdPartyResource) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ThirdPartyResourceList) IsAnAPIObject() {} func (obj *ThirdPartyResourceList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*DaemonSet) IsAnAPIObject() {} func (obj *DaemonSet) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*DaemonSetList) IsAnAPIObject() {} func (obj *DaemonSetList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ThirdPartyResourceData) IsAnAPIObject() {} func (obj *ThirdPartyResourceData) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ThirdPartyResourceDataList) IsAnAPIObject() {} func (obj *ThirdPartyResourceDataList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*Ingress) IsAnAPIObject() {} func (obj *Ingress) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*IngressList) IsAnAPIObject() {} func (obj *IngressList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ListOptions) IsAnAPIObject() {} func (obj *ListOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -51,5 +51,5 @@ func addKnownTypes() {
) )
} }
func (*RawNode) IsAnAPIObject() {} func (obj *RawNode) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*RawPod) IsAnAPIObject() {} func (obj *RawPod) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -43,5 +43,5 @@ func addKnownTypes() {
) )
} }
func (*RawNode) IsAnAPIObject() {} func (obj *RawNode) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*RawPod) IsAnAPIObject() {} func (obj *RawPod) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -365,7 +365,7 @@ func (s *SimpleStream) Close() error {
return nil return nil
} }
func (s *SimpleStream) IsAnAPIObject() {} func (obj *SimpleStream) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
func (s *SimpleStream) InputStream(version, accept string) (io.ReadCloser, bool, string, error) { func (s *SimpleStream) InputStream(version, accept string) (io.ReadCloser, bool, string, error) {
s.version = version s.version = version
@ -2680,7 +2680,9 @@ type UnregisteredAPIObject struct {
Value string Value string
} }
func (*UnregisteredAPIObject) IsAnAPIObject() {} func (obj *UnregisteredAPIObject) GetObjectKind() unversioned.ObjectKind {
return unversioned.EmptyObjectKind
}
func TestWriteJSONDecodeError(t *testing.T) { func TestWriteJSONDecodeError(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {

View File

@ -45,7 +45,7 @@ type testPatchSubType struct {
StringField string `json:"theField"` StringField string `json:"theField"`
} }
func (*testPatchType) IsAnAPIObject() {} func (obj *testPatchType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func TestPatchAnonymousField(t *testing.T) { func TestPatchAnonymousField(t *testing.T) {
originalJS := `{"kind":"testPatchType","theField":"my-value"}` originalJS := `{"kind":"testPatchType","theField":"my-value"}`

View File

@ -28,7 +28,7 @@ type Simple struct {
Labels map[string]string `json:"labels,omitempty"` Labels map[string]string `json:"labels,omitempty"`
} }
func (*Simple) IsAnAPIObject() {} func (obj *Simple) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
type SimpleRoot struct { type SimpleRoot struct {
unversioned.TypeMeta `json:",inline"` unversioned.TypeMeta `json:",inline"`
@ -37,7 +37,7 @@ type SimpleRoot struct {
Labels map[string]string `json:"labels,omitempty"` Labels map[string]string `json:"labels,omitempty"`
} }
func (*SimpleRoot) IsAnAPIObject() {} func (obj *SimpleRoot) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
type SimpleGetOptions struct { type SimpleGetOptions struct {
unversioned.TypeMeta `json:",inline"` unversioned.TypeMeta `json:",inline"`
@ -53,7 +53,7 @@ func (SimpleGetOptions) SwaggerDoc() map[string]string {
} }
} }
func (*SimpleGetOptions) IsAnAPIObject() {} func (obj *SimpleGetOptions) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
type SimpleList struct { type SimpleList struct {
unversioned.TypeMeta `json:",inline"` unversioned.TypeMeta `json:",inline"`
@ -61,4 +61,4 @@ type SimpleList struct {
Items []Simple `json:"items,omitempty"` Items []Simple `json:"items,omitempty"`
} }
func (*SimpleList) IsAnAPIObject() {} func (obj *SimpleList) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -59,7 +59,7 @@ func MetaNamespaceIndexFunc(obj interface{}) ([]string, error) {
if err != nil { if err != nil {
return []string{""}, fmt.Errorf("object has no meta: %v", err) return []string{""}, fmt.Errorf("object has no meta: %v", err)
} }
return []string{meta.Namespace()}, nil return []string{meta.GetNamespace()}, nil
} }
// Index maps the indexed value to a set of keys in the store that match on that value // Index maps the indexed value to a set of keys in the store that match on that value

View File

@ -240,7 +240,7 @@ func (r *Reflector) ListAndWatch(stopCh <-chan struct{}) error {
if err != nil { if err != nil {
return fmt.Errorf("%s: Unable to understand list result %#v", r.name, list) return fmt.Errorf("%s: Unable to understand list result %#v", r.name, list)
} }
resourceVersion = metaInterface.ResourceVersion() resourceVersion = metaInterface.GetResourceVersion()
items, err := meta.ExtractList(list) items, err := meta.ExtractList(list)
if err != nil { if err != nil {
return fmt.Errorf("%s: Unable to understand list result %#v (%v)", r.name, list, err) return fmt.Errorf("%s: Unable to understand list result %#v (%v)", r.name, list, err)
@ -335,7 +335,7 @@ loop:
util.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", r.name, event)) util.HandleError(fmt.Errorf("%s: unable to understand watch event %#v", r.name, event))
continue continue
} }
newResourceVersion := meta.ResourceVersion() newResourceVersion := meta.GetResourceVersion()
switch event.Type { switch event.Type {
case watch.Added: case watch.Added:
r.store.Add(event.Object) r.store.Add(event.Object)

View File

@ -80,10 +80,10 @@ func MetaNamespaceKeyFunc(obj interface{}) (string, error) {
if err != nil { if err != nil {
return "", fmt.Errorf("object has no meta: %v", err) return "", fmt.Errorf("object has no meta: %v", err)
} }
if len(meta.Namespace()) > 0 { if len(meta.GetNamespace()) > 0 {
return meta.Namespace() + "/" + meta.Name(), nil return meta.GetNamespace() + "/" + meta.GetName(), nil
} }
return meta.Name(), nil return meta.GetName(), nil
} }
// SplitMetaNamespaceKey returns the namespace and name that // SplitMetaNamespaceKey returns the namespace and name that

View File

@ -34,4 +34,10 @@ func init() {
) )
} }
func (*Config) IsAnAPIObject() {} func (obj *Config) GetObjectKind() unversioned.ObjectKind { return obj }
func (obj *Config) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *Config) GroupVersionKind() *unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}

View File

@ -35,4 +35,10 @@ func init() {
) )
} }
func (*Config) IsAnAPIObject() {} func (obj *Config) GetObjectKind() unversioned.ObjectKind { return obj }
func (obj *Config) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *Config) GroupVersionKind() *unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}

View File

@ -226,7 +226,8 @@ func TestRequestURI(t *testing.T) {
type NotAnAPIObject struct{} type NotAnAPIObject struct{}
func (NotAnAPIObject) IsAnAPIObject() {} func (obj NotAnAPIObject) GroupVersionKind() *unversioned.GroupVersionKind { return nil }
func (obj NotAnAPIObject) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {}
func TestRequestBody(t *testing.T) { func TestRequestBody(t *testing.T) {
// test unknown type // test unknown type

View File

@ -38,7 +38,7 @@ func nameIndexFunc(obj interface{}) ([]string, error) {
if err != nil { if err != nil {
return []string{""}, fmt.Errorf("object has no meta: %v", err) return []string{""}, fmt.Errorf("object has no meta: %v", err)
} }
return []string{meta.Name()}, nil return []string{meta.GetName()}, nil
} }
// ServiceAccountsControllerOptions contains options for running a ServiceAccountsController // ServiceAccountsControllerOptions contains options for running a ServiceAccountsController

View File

@ -80,7 +80,20 @@ func (f SimpleMetaFactory) Update(version, kind string, obj interface{}) error {
// on a pointer to a struct to version and kind. Provided as a convenience for others // on a pointer to a struct to version and kind. Provided as a convenience for others
// implementing MetaFactory. Pass an array to baseFields to check one or more nested structs // implementing MetaFactory. Pass an array to baseFields to check one or more nested structs
// for the named fields. The version field is treated as optional if it is not present in the struct. // for the named fields. The version field is treated as optional if it is not present in the struct.
// TODO: this method is on its way out
func UpdateVersionAndKind(baseFields []string, versionField, version, kindField, kind string, obj interface{}) error { func UpdateVersionAndKind(baseFields []string, versionField, version, kindField, kind string, obj interface{}) error {
if typed, ok := obj.(unversioned.ObjectKind); ok {
if len(version) == 0 && len(kind) == 0 {
typed.SetGroupVersionKind(nil)
} else {
gv, err := unversioned.ParseGroupVersion(version)
if err != nil {
return err
}
typed.SetGroupVersionKind(&unversioned.GroupVersionKind{Group: gv.Group, Version: gv.Version, Kind: kind})
}
return nil
}
v, err := EnforcePtr(obj) v, err := EnforcePtr(obj)
if err != nil { if err != nil {
return err return err

View File

@ -14,13 +14,15 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package queryparams package queryparams_test
import ( import (
"net/url" "net/url"
"reflect" "reflect"
"testing" "testing"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/conversion/queryparams"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
@ -38,7 +40,7 @@ type bar struct {
Ignored2 string Ignored2 string
} }
func (*bar) IsAnAPIObject() {} func (obj *bar) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
type foo struct { type foo struct {
Str string `json:"str"` Str string `json:"str"`
@ -51,14 +53,14 @@ type foo struct {
Testmap map[string]string `json:"testmap,omitempty"` Testmap map[string]string `json:"testmap,omitempty"`
} }
func (*foo) IsAnAPIObject() {} func (obj *foo) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
type baz struct { type baz struct {
Ptr *int `json:"ptr"` Ptr *int `json:"ptr"`
Bptr *bool `json:"bptr,omitempty"` Bptr *bool `json:"bptr,omitempty"`
} }
func (*baz) IsAnAPIObject() {} func (obj *baz) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
func validateResult(t *testing.T, input interface{}, actual, expected url.Values) { func validateResult(t *testing.T, input interface{}, actual, expected url.Values) {
local := url.Values{} local := url.Values{}
@ -160,7 +162,7 @@ func TestConvert(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
result, err := Convert(test.input) result, err := queryparams.Convert(test.input)
if err != nil { if err != nil {
t.Errorf("Unexpected error while converting %#v: %v", test.input, err) t.Errorf("Unexpected error while converting %#v: %v", test.input, err)
} }

View File

@ -47,13 +47,13 @@ func ExtractFieldPathAsString(obj interface{}, fieldPath string) (string, error)
switch fieldPath { switch fieldPath {
case "metadata.annotations": case "metadata.annotations":
return formatMap(accessor.Annotations()), nil return formatMap(accessor.GetAnnotations()), nil
case "metadata.labels": case "metadata.labels":
return formatMap(accessor.Labels()), nil return formatMap(accessor.GetLabels()), nil
case "metadata.name": case "metadata.name":
return accessor.Name(), nil return accessor.GetName(), nil
case "metadata.namespace": case "metadata.namespace":
return accessor.Namespace(), nil return accessor.GetNamespace(), nil
} }
return "", fmt.Errorf("Unsupported fieldPath: %v", fieldPath) return "", fmt.Errorf("Unsupported fieldPath: %v", fieldPath)

View File

@ -92,7 +92,7 @@ func GetModifiedConfiguration(info *resource.Info, annotate bool) ([]byte, error
} }
// Get the current annotations from the object. // Get the current annotations from the object.
annotations := accessor.Annotations() annotations := accessor.GetAnnotations()
if annotations == nil { if annotations == nil {
annotations = map[string]string{} annotations = map[string]string{}
} }

View File

@ -64,9 +64,27 @@ type ExternalType2 struct {
Name string `json:"name"` Name string `json:"name"`
} }
func (*internalType) IsAnAPIObject() {} func (obj *internalType) GetObjectKind() unversioned.ObjectKind { return obj }
func (*externalType) IsAnAPIObject() {} func (obj *internalType) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
func (*ExternalType2) IsAnAPIObject() {} obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *internalType) GroupVersionKind() *unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
func (obj *externalType) GetObjectKind() unversioned.ObjectKind { return obj }
func (obj *externalType) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *externalType) GroupVersionKind() *unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
func (obj *ExternalType2) GetObjectKind() unversioned.ObjectKind { return obj }
func (obj *ExternalType2) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *ExternalType2) GroupVersionKind() *unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
var versionErr = errors.New("not a version") var versionErr = errors.New("not a version")

View File

@ -85,11 +85,11 @@ type TestPrintType struct {
Data string Data string
} }
func (*TestPrintType) IsAnAPIObject() {} func (obj *TestPrintType) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
type TestUnknownType struct{} type TestUnknownType struct{}
func (*TestUnknownType) IsAnAPIObject() {} func (obj *TestUnknownType) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
func TestPrinter(t *testing.T) { func TestPrinter(t *testing.T) {
//test inputs //test inputs

View File

@ -103,7 +103,7 @@ type ServiceReaper struct {
type objInterface interface { type objInterface interface {
Delete(name string) error Delete(name string) error
Get(name string) (meta.Interface, error) Get(name string) (meta.Object, error)
} }
// getOverlappingControllers finds rcs that this controller overlaps, as well as rcs overlapping this controller. // getOverlappingControllers finds rcs that this controller overlaps, as well as rcs overlapping this controller.

View File

@ -30,4 +30,4 @@ type TestStruct struct {
IntList []int `json:"IntList"` IntList []int `json:"IntList"`
} }
func (ts *TestStruct) IsAnAPIObject() {} func (obj *TestStruct) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -443,7 +443,7 @@ func (e *Etcd) DeleteCollection(ctx api.Context, options *api.DeleteOptions, lis
if err != nil { if err != nil {
return nil, err return nil, err
} }
if _, err := e.Delete(ctx, accessor.Name(), options); err != nil { if _, err := e.Delete(ctx, accessor.GetName(), options); err != nil {
return nil, err return nil, err
} }
} }

View File

@ -20,6 +20,7 @@ import (
"errors" "errors"
"testing" "testing"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
@ -33,8 +34,8 @@ type IgnoredList struct {
Items []Ignored Items []Ignored
} }
func (*Ignored) IsAnAPIObject() {} func (obj *Ignored) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
func (*IgnoredList) IsAnAPIObject() {} func (obj *IgnoredList) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
func TestSelectionPredicate(t *testing.T) { func TestSelectionPredicate(t *testing.T) {
table := map[string]struct { table := map[string]struct {

View File

@ -23,6 +23,7 @@ import (
"strings" "strings"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/api/unversioned"
) )
// LocationStreamer is a resource that streams the contents of a particular // LocationStreamer is a resource that streams the contents of a particular
@ -38,8 +39,9 @@ type LocationStreamer struct {
// a LocationStreamer must implement a rest.ResourceStreamer // a LocationStreamer must implement a rest.ResourceStreamer
var _ rest.ResourceStreamer = &LocationStreamer{} var _ rest.ResourceStreamer = &LocationStreamer{}
// IsAnAPIObject marks this object as a runtime.Object func (obj *LocationStreamer) GetObjectKind() unversioned.ObjectKind {
func (*LocationStreamer) IsAnAPIObject() {} return unversioned.EmptyObjectKind
}
// InputStream returns a stream with the contents of the URL location. If no location is provided, // InputStream returns a stream with the contents of the URL location. If no location is provided,
// a null stream is returned. // a null stream is returned.

View File

@ -25,7 +25,7 @@ import (
) )
type InternalComplex struct { type InternalComplex struct {
TypeMeta runtime.TypeMeta
String string String string
Integer int Integer int
Integer64 int64 Integer64 int64
@ -34,16 +34,16 @@ type InternalComplex struct {
} }
type ExternalComplex struct { type ExternalComplex struct {
TypeMeta `json:",inline"` runtime.TypeMeta `json:",inline"`
String string `json:"string" description:"testing"` String string `json:"string" description:"testing"`
Integer int `json:"int"` Integer int `json:"int"`
Integer64 int64 `json:",omitempty"` Integer64 int64 `json:",omitempty"`
Int64 int64 Int64 int64
Bool bool `json:"bool"` Bool bool `json:"bool"`
} }
func (*InternalComplex) IsAnAPIObject() {} func (obj *InternalComplex) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ExternalComplex) IsAnAPIObject() {} func (obj *ExternalComplex) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func TestStringMapConversion(t *testing.T) { func TestStringMapConversion(t *testing.T) {
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""} internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}

View File

@ -56,10 +56,10 @@ type ObjectTestExternal struct {
Items []runtime.RawExtension `json:"items,omitempty"` Items []runtime.RawExtension `json:"items,omitempty"`
} }
func (*ObjectTest) IsAnAPIObject() {} func (obj *ObjectTest) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ObjectTestExternal) IsAnAPIObject() {} func (obj *ObjectTestExternal) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*EmbeddedTest) IsAnAPIObject() {} func (obj *EmbeddedTest) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*EmbeddedTestExternal) IsAnAPIObject() {} func (obj *EmbeddedTestExternal) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func TestDecodeEmptyRawExtensionAsObject(t *testing.T) { func TestDecodeEmptyRawExtensionAsObject(t *testing.T) {
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""} internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}

View File

@ -140,11 +140,10 @@ type SelfLinker interface {
Namespace(obj Object) (string, error) Namespace(obj Object) (string, error)
} }
// All api types must support the Object interface. It's deliberately tiny so that this is not an onerous // All API types registered with Scheme must support the Object interface. Since objects in a scheme are
// burden. Implement it with a pointer receiver; this will allow us to use the go compiler to check the // expected to be serialized to the wire, the interface an Object must provide to the Scheme allows
// one thing about our objects that it's capable of checking for us. // serializers to set the kind, version, and group the object is represented as. An Object may choose
// to return a no-op ObjectKindAccessor in cases where it is not expected to be serialized.
type Object interface { type Object interface {
// This function is used only to enforce membership. It's never called. GetObjectKind() unversioned.ObjectKind
// TODO: Consider mass rename in the future to make it do something useful.
IsAnAPIObject()
} }

44
pkg/runtime/register.go Normal file
View File

@ -0,0 +1,44 @@
/*
Copyright 2015 The Kubernetes Authors 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 runtime
import (
"k8s.io/kubernetes/pkg/api/unversioned"
)
// SetGroupVersionKind satisfies the ObjectKind interface for all objects that embed PluginBase
func (obj *PluginBase) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
_, obj.Kind = gvk.ToAPIVersionAndKind()
}
// GroupVersionKind satisfies the ObjectKind interface for all objects that embed PluginBase
func (obj *PluginBase) GroupVersionKind() *unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind("", obj.Kind)
}
// SetGroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta
func (obj *TypeMeta) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
// GroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta
func (obj *TypeMeta) GroupVersionKind() *unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
func (obj *Unknown) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *Unstructured) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -30,6 +30,16 @@ type TypeMeta struct {
APIVersion string `json:"apiVersion,omitempty"` APIVersion string `json:"apiVersion,omitempty"`
} }
// SetGroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta
func (obj *TypeMeta) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.APIVersion, obj.Kind = gvk.ToAPIVersionAndKind()
}
// GroupVersionKind satisfies the ObjectKind interface for all objects that embed TypeMeta
func (obj *TypeMeta) GroupVersionKind() *unversioned.GroupVersionKind {
return unversioned.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
type InternalSimple struct { type InternalSimple struct {
TypeMeta `json:",inline"` TypeMeta `json:",inline"`
TestString string `json:"testString"` TestString string `json:"testString"`
@ -40,8 +50,14 @@ type ExternalSimple struct {
TestString string `json:"testString"` TestString string `json:"testString"`
} }
func (*InternalSimple) IsAnAPIObject() {} func (obj *InternalSimple) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (*ExternalSimple) IsAnAPIObject() {} func (obj *InternalSimple) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *ExternalSimple) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *ExternalSimple) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
}
func TestScheme(t *testing.T) { func TestScheme(t *testing.T) {
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""} internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
@ -197,12 +213,30 @@ type InternalOptionalExtensionType struct {
Extension runtime.EmbeddedObject `json:"extension,omitempty"` Extension runtime.EmbeddedObject `json:"extension,omitempty"`
} }
func (*ExtensionA) IsAnAPIObject() {} func (obj *ExtensionA) GetObjectKind() unversioned.ObjectKind { return &obj.PluginBase }
func (*ExtensionB) IsAnAPIObject() {} func (obj *ExtensionA) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
func (*ExternalExtensionType) IsAnAPIObject() {} _, obj.PluginBase.Kind = gvk.ToAPIVersionAndKind()
func (*InternalExtensionType) IsAnAPIObject() {} }
func (*ExternalOptionalExtensionType) IsAnAPIObject() {} func (obj *ExtensionB) GetObjectKind() unversioned.ObjectKind { return &obj.PluginBase }
func (*InternalOptionalExtensionType) IsAnAPIObject() {} func (obj *ExtensionB) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
_, obj.PluginBase.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *ExternalExtensionType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *ExternalExtensionType) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *InternalExtensionType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *InternalExtensionType) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *ExternalOptionalExtensionType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *ExternalOptionalExtensionType) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
}
func (obj *InternalOptionalExtensionType) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func (obj *InternalOptionalExtensionType) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) {
obj.TypeMeta.APIVersion, obj.TypeMeta.Kind = gvk.ToAPIVersionAndKind()
}
func TestExternalToInternalMapping(t *testing.T) { func TestExternalToInternalMapping(t *testing.T) {
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""} internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}

View File

@ -25,7 +25,7 @@ package runtime
// runtime.TypeMeta `json:",inline"` // runtime.TypeMeta `json:",inline"`
// ... // other fields // ... // other fields
// } // }
// func (*MyAwesomeAPIObject) IsAnAPIObject() {} // func (obj *MyAwesomeAPIObject) SetGroupVersionKind(gvk *unversioned.GroupVersionKind) { unversioned.UpdateTypeMeta(obj,gvk) }; GroupVersionKind() *GroupVersionKind
// //
// TypeMeta is provided here for convenience. You may use it directly from this package or define // TypeMeta is provided here for convenience. You may use it directly from this package or define
// your own with the same fields. // your own with the same fields.
@ -120,8 +120,6 @@ type Unknown struct {
RawJSON []byte RawJSON []byte
} }
func (*Unknown) IsAnAPIObject() {}
// Unstructured allows objects that do not have Golang structs registered to be manipulated // Unstructured allows objects that do not have Golang structs registered to be manipulated
// generically. This can be used to deal with the API objects from a plug-in. Unstructured // generically. This can be used to deal with the API objects from a plug-in. Unstructured
// objects still have functioning TypeMeta features-- kind, version, etc. // objects still have functioning TypeMeta features-- kind, version, etc.
@ -133,5 +131,3 @@ type Unstructured struct {
// children. // children.
Object map[string]interface{} Object map[string]interface{}
} }
func (*Unstructured) IsAnAPIObject() {}

View File

@ -280,7 +280,7 @@ func TestFiltering(t *testing.T) {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
return false return false
} }
return selector.Matches(labels.Set(metadata.Labels())) return selector.Matches(labels.Set(metadata.GetLabels()))
} }
// We want to observe fooCreation too, so need to pass smaller resource version. // We want to observe fooCreation too, so need to pass smaller resource version.
initialVersion, err := strconv.Atoi(fooCreated.ResourceVersion) initialVersion, err := strconv.Atoi(fooCreated.ResourceVersion)

View File

@ -27,4 +27,4 @@ type TestResource struct {
Value int `json:"value"` Value int `json:"value"`
} }
func (*TestResource) IsAnAPIObject() {} func (obj *TestResource) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -38,7 +38,7 @@ func CreateObjList(prefix string, helper storage.Interface, items []runtime.Obje
if err != nil { if err != nil {
return err return err
} }
err = CreateObj(helper, path.Join(prefix, meta.Name()), obj, obj, 0) err = CreateObj(helper, path.Join(prefix, meta.GetName()), obj, obj, 0)
if err != nil { if err != nil {
return err return err
} }

View File

@ -71,11 +71,11 @@ func NamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
name := meta.Name() name := meta.GetName()
if ok, msg := validation.IsValidPathSegmentName(name); !ok { if ok, msg := validation.IsValidPathSegmentName(name); !ok {
return "", fmt.Errorf("invalid name: %v", msg) return "", fmt.Errorf("invalid name: %v", msg)
} }
return prefix + "/" + meta.Namespace() + "/" + meta.Name(), nil return prefix + "/" + meta.GetNamespace() + "/" + name, nil
} }
func NoNamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) { func NoNamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) {
@ -83,9 +83,9 @@ func NoNamespaceKeyFunc(prefix string, obj runtime.Object) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
name := meta.Name() name := meta.GetName()
if ok, msg := validation.IsValidPathSegmentName(name); !ok { if ok, msg := validation.IsValidPathSegmentName(name); !ok {
return "", fmt.Errorf("invalid name: %v", msg) return "", fmt.Errorf("invalid name: %v", msg)
} }
return prefix + "/" + meta.Name(), nil return prefix + "/" + name, nil
} }

View File

@ -142,7 +142,7 @@ func objectToVersionedRuntimeObject(obj interface{}) (runtime.Object, uint64, er
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
resourceVersion, err := parseResourceVersion(meta.ResourceVersion()) resourceVersion, err := parseResourceVersion(meta.GetResourceVersion())
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }

View File

@ -19,6 +19,7 @@ package watch
import ( import (
"sync" "sync"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
@ -80,7 +81,9 @@ const internalRunFunctionMarker = "internal-do-function"
// a function type we can shoehorn into the queue. // a function type we can shoehorn into the queue.
type functionFakeRuntimeObject func() type functionFakeRuntimeObject func()
func (functionFakeRuntimeObject) IsAnAPIObject() {} func (obj functionFakeRuntimeObject) GetObjectKind() unversioned.ObjectKind {
return unversioned.EmptyObjectKind
}
// Execute f, blocking the incoming queue (and waiting for it to drain first). // Execute f, blocking the incoming queue (and waiting for it to drain first).
// The purpose of this terrible hack is so that watchers added after an event // The purpose of this terrible hack is so that watchers added after an event

View File

@ -22,6 +22,7 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
) )
@ -30,7 +31,7 @@ type myType struct {
Value string Value string
} }
func (*myType) IsAnAPIObject() {} func (obj *myType) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
func TestBroadcaster(t *testing.T) { func TestBroadcaster(t *testing.T) {
table := []Event{ table := []Event{

View File

@ -18,11 +18,13 @@ package watch
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api/unversioned"
) )
type testType string type testType string
func (testType) IsAnAPIObject() {} func (obj testType) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
func TestFake(t *testing.T) { func TestFake(t *testing.T) {
f := NewFake() f := NewFake()

View File

@ -34,4 +34,4 @@ func init() {
) )
} }
func (*Policy) IsAnAPIObject() {} func (obj *Policy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }

View File

@ -35,4 +35,4 @@ func init() {
) )
} }
func (*Policy) IsAnAPIObject() {} func (obj *Policy) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }