Move typemeta.go to api/meta/meta.go

Prepares for the meta object to front multiple underlying types
when TypeMeta and ObjectMeta is split in internal and v1beta3, but
combined in v1beta1 and v1beta2
pull/6/head
Clayton Coleman 2014-10-22 22:28:06 -04:00
parent dd8c49fc47
commit 64d98cba73
12 changed files with 71 additions and 49 deletions

View File

@ -31,6 +31,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubecfg"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -372,7 +373,7 @@ func executeAPIRequest(ctx api.Context, method string, c *client.Client) bool {
if err != nil {
glog.Fatalf("error obtaining resource version for update: %v", err)
}
jsonBase, err := runtime.FindTypeMeta(obj)
jsonBase, err := meta.FindTypeMeta(obj)
if err != nil {
glog.Fatalf("error finding json base for update: %v", err)
}
@ -408,7 +409,7 @@ func executeAPIRequest(ctx api.Context, method string, c *client.Client) bool {
if err != nil {
glog.Fatalf("error setting resource version: %v", err)
}
jsonBase, err := runtime.FindTypeMeta(obj)
jsonBase, err := meta.FindTypeMeta(obj)
if err != nil {
glog.Fatalf("error setting resource version: %v", err)
}

View File

@ -20,6 +20,7 @@ import (
"fmt"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -47,13 +48,13 @@ var Codec = v1beta1.Codec
// ResourceVersioner describes a default versioner that can handle all types
// of versioning.
// TODO: when versioning changes, make this part of each API definition.
var ResourceVersioner = runtime.NewTypeMetaResourceVersioner()
var ResourceVersioner = meta.NewTypeMetaResourceVersioner()
// SelfLinker can set or get the SelfLink field of all API types.
// TODO: when versioning changes, make this part of each API definition.
// TODO(lavalamp): Combine SelfLinker & ResourceVersioner interfaces, force all uses
// to go through the InterfacesFor method below.
var SelfLinker = runtime.NewTypeMetaSelfLinker()
var SelfLinker = meta.NewTypeMetaSelfLinker()
// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
type VersionInterfaces struct {

19
pkg/api/meta/doc.go Normal file
View File

@ -0,0 +1,19 @@
/*
Copyright 2014 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package meta provides functions for retrieving API metadata from objects
// belonging to the Kubernetes API
package meta

View File

@ -14,18 +14,19 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package runtime
package meta
import (
"fmt"
"reflect"
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
// FindTypeMeta takes an arbitary api type, returns pointer to its TypeMeta field.
// obj must be a pointer to an api type.
func FindTypeMeta(obj Object) (TypeMetaInterface, error) {
func FindTypeMeta(obj runtime.Object) (TypeMetaInterface, error) {
v, err := conversion.EnforcePtr(obj)
if err != nil {
return nil, err
@ -48,14 +49,14 @@ func FindTypeMeta(obj Object) (TypeMetaInterface, error) {
// NewTypeMetaResourceVersioner returns a ResourceVersioner that can set or
// retrieve ResourceVersion on objects derived from TypeMeta.
func NewTypeMetaResourceVersioner() ResourceVersioner {
func NewTypeMetaResourceVersioner() runtime.ResourceVersioner {
return jsonBaseModifier{}
}
// jsonBaseModifier implements ResourceVersioner and SelfLinker.
type jsonBaseModifier struct{}
func (v jsonBaseModifier) ResourceVersion(obj Object) (string, error) {
func (v jsonBaseModifier) ResourceVersion(obj runtime.Object) (string, error) {
json, err := FindTypeMeta(obj)
if err != nil {
return "", err
@ -63,7 +64,7 @@ func (v jsonBaseModifier) ResourceVersion(obj Object) (string, error) {
return json.ResourceVersion(), nil
}
func (v jsonBaseModifier) SetResourceVersion(obj Object, version string) error {
func (v jsonBaseModifier) SetResourceVersion(obj runtime.Object, version string) error {
json, err := FindTypeMeta(obj)
if err != nil {
return err
@ -72,7 +73,7 @@ func (v jsonBaseModifier) SetResourceVersion(obj Object, version string) error {
return nil
}
func (v jsonBaseModifier) ID(obj Object) (string, error) {
func (v jsonBaseModifier) ID(obj runtime.Object) (string, error) {
json, err := FindTypeMeta(obj)
if err != nil {
return "", err
@ -80,7 +81,7 @@ func (v jsonBaseModifier) ID(obj Object) (string, error) {
return json.ID(), nil
}
func (v jsonBaseModifier) SelfLink(obj Object) (string, error) {
func (v jsonBaseModifier) SelfLink(obj runtime.Object) (string, error) {
json, err := FindTypeMeta(obj)
if err != nil {
return "", err
@ -88,7 +89,7 @@ func (v jsonBaseModifier) SelfLink(obj Object) (string, error) {
return json.SelfLink(), nil
}
func (v jsonBaseModifier) SetSelfLink(obj Object, selfLink string) error {
func (v jsonBaseModifier) SetSelfLink(obj runtime.Object, selfLink string) error {
json, err := FindTypeMeta(obj)
if err != nil {
return err
@ -98,12 +99,12 @@ func (v jsonBaseModifier) SetSelfLink(obj Object, selfLink string) error {
}
// NewTypeMetaSelfLinker returns a SelfLinker that works on all TypeMeta SelfLink fields.
func NewTypeMetaSelfLinker() SelfLinker {
func NewTypeMetaSelfLinker() runtime.SelfLinker {
return jsonBaseModifier{}
}
// TypeMetaInterface lets you work with a TypeMeta from any of the versioned or
// internal APIObjects.
// internal APIruntime.Objects.
type TypeMetaInterface interface {
ID() string
SetID(ID string)

View File

@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package runtime
package meta
import (
"reflect"
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
@ -86,7 +87,7 @@ func TestGenericTypeMeta(t *testing.T) {
}
type MyAPIObject struct {
TypeMeta `yaml:",inline" json:",inline"`
runtime.TypeMeta `yaml:",inline" json:",inline"`
}
func (*MyAPIObject) IsAnAPIObject() {}
@ -98,13 +99,13 @@ func (*MyIncorrectlyMarkedAsAPIObject) IsAnAPIObject() {}
func TestResourceVersionerOfAPI(t *testing.T) {
type T struct {
Object
runtime.Object
Expected string
}
testCases := map[string]T{
"empty api object": {&MyAPIObject{}, ""},
"api object with version": {&MyAPIObject{TypeMeta: TypeMeta{ResourceVersion: "1"}}, "1"},
"pointer to api object with version": {&MyAPIObject{TypeMeta: TypeMeta{ResourceVersion: "1"}}, "1"},
"api object with version": {&MyAPIObject{TypeMeta: runtime.TypeMeta{ResourceVersion: "1"}}, "1"},
"pointer to api object with version": {&MyAPIObject{TypeMeta: runtime.TypeMeta{ResourceVersion: "1"}}, "1"},
}
versioning := NewTypeMetaResourceVersioner()
for key, testCase := range testCases {
@ -118,7 +119,7 @@ func TestResourceVersionerOfAPI(t *testing.T) {
}
failingCases := map[string]struct {
Object
runtime.Object
Expected string
}{
"not a valid object to try": {&MyIncorrectlyMarkedAsAPIObject{}, "1"},
@ -131,10 +132,10 @@ func TestResourceVersionerOfAPI(t *testing.T) {
}
setCases := map[string]struct {
Object
runtime.Object
Expected string
}{
"pointer to api object with version": {&MyAPIObject{TypeMeta: TypeMeta{ResourceVersion: "1"}}, "1"},
"pointer to api object with version": {&MyAPIObject{TypeMeta: runtime.TypeMeta{ResourceVersion: "1"}}, "1"},
}
for key, testCase := range setCases {
if err := versioning.SetResourceVersion(testCase.Object, "5"); err != nil {
@ -152,13 +153,13 @@ func TestResourceVersionerOfAPI(t *testing.T) {
func TestTypeMetaSelfLinker(t *testing.T) {
table := map[string]struct {
obj Object
obj runtime.Object
expect string
try string
succeed bool
}{
"normal": {
obj: &MyAPIObject{TypeMeta: TypeMeta{SelfLink: "foobar"}},
obj: &MyAPIObject{TypeMeta: runtime.TypeMeta{SelfLink: "foobar"}},
expect: "foobar",
try: "newbar",
succeed: true,

View File

@ -21,6 +21,7 @@ import (
"fmt"
"regexp"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
@ -35,7 +36,7 @@ func GetReference(obj runtime.Object) (*ObjectReference, error) {
if obj == nil {
return nil, ErrNilObject
}
jsonBase, err := runtime.FindTypeMeta(obj)
jsonBase, err := meta.FindTypeMeta(obj)
if err != nil {
return nil, err
}

View File

@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -46,17 +47,6 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs(
// APIVersion and Kind must remain blank in memory.
j.APIVersion = ""
j.Kind = ""
j.Name = c.RandString()
// TODO: Fix JSON/YAML packages and/or write custom encoding
// for uint64's. Somehow the LS *byte* of this is lost, but
// only when all 8 bytes are set.
j.ResourceVersion = strconv.FormatUint(c.RandUint64()>>8, 10)
j.SelfLink = c.RandString()
var sec, nsec int64
c.Fuzz(&sec)
c.Fuzz(&nsec)
j.CreationTimestamp = util.Unix(sec, nsec).Rfc3339Copy()
},
func(j *api.TypeMeta, c fuzz.Continue) {
// We have to customize the randomization of TypeMetas because their
@ -111,7 +101,7 @@ var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs(
func runTest(t *testing.T, codec runtime.Codec, source runtime.Object) {
name := reflect.TypeOf(source).Elem().Name()
apiObjectFuzzer.Fuzz(source)
j, err := runtime.FindTypeMeta(source)
j, err := meta.FindTypeMeta(source)
if err != nil {
t.Fatalf("Unexpected error %v for %#v", err, source)
}
@ -170,7 +160,7 @@ func TestTypes(t *testing.T) {
t.Errorf("Couldn't make a %v? %v", kind, err)
continue
}
if _, err := runtime.FindTypeMeta(item); err != nil {
if _, err := meta.FindTypeMeta(item); err != nil {
t.Logf("%s is not a TypeMeta and cannot be round tripped: %v", kind, err)
continue
}

View File

@ -23,6 +23,7 @@ import (
"time"
apierrs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@ -78,7 +79,7 @@ func (r *Reflector) listAndWatch() {
glog.Errorf("Failed to list %v: %v", r.expectedType, err)
return
}
jsonBase, err := runtime.FindTypeMeta(list)
jsonBase, err := meta.FindTypeMeta(list)
if err != nil {
glog.Errorf("Unable to understand list result %#v", list)
return
@ -112,7 +113,7 @@ func (r *Reflector) listAndWatch() {
func (r *Reflector) syncWith(items []runtime.Object) error {
found := map[string]interface{}{}
for _, item := range items {
jsonBase, err := runtime.FindTypeMeta(item)
jsonBase, err := meta.FindTypeMeta(item)
if err != nil {
return fmt.Errorf("unexpected item in list: %v", err)
}
@ -139,7 +140,7 @@ func (r *Reflector) watchHandler(w watch.Interface, resourceVersion *string) err
glog.Errorf("expected type %v, but watch event object had type %v", e, a)
continue
}
jsonBase, err := runtime.FindTypeMeta(event.Object)
jsonBase, err := meta.FindTypeMeta(event.Object)
if err != nil {
glog.Errorf("unable to understand watch event %#v", event)
continue

View File

@ -20,6 +20,7 @@ import (
"fmt"
"io"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
@ -109,7 +110,7 @@ func doUpdate(c *client.RESTClient, resource string, obj runtime.Object) (string
// Update the object we are trying to send to the server with the
// correct resource version.
typeMeta, err := runtime.FindTypeMeta(obj)
typeMeta, err := meta.FindTypeMeta(obj)
if err != nil {
return "", err
}
@ -149,7 +150,7 @@ func doDelete(c *client.RESTClient, resource string, obj runtime.Object) (string
}
func getIDFromObj(obj runtime.Object) (string, error) {
typeMeta, err := runtime.FindTypeMeta(obj)
typeMeta, err := meta.FindTypeMeta(obj)
if err != nil {
return "", err
}
@ -157,7 +158,7 @@ func getIDFromObj(obj runtime.Object) (string, error) {
}
func getResourceVersionFromObj(obj runtime.Object) (string, error) {
typeMeta, err := runtime.FindTypeMeta(obj)
typeMeta, err := meta.FindTypeMeta(obj)
if err != nil {
return "", err
}

View File

@ -29,12 +29,14 @@ var Codec = runtime.CodecFor(scheme, "v1test")
type EmbeddedTest struct {
runtime.TypeMeta `yaml:",inline" json:",inline"`
ID string `yaml:"id,omitempty" json:"id,omitempty"`
Object runtime.EmbeddedObject `yaml:"object,omitempty" json:"object,omitempty"`
EmptyObject runtime.EmbeddedObject `yaml:"emptyObject,omitempty" json:"emptyObject,omitempty"`
}
type EmbeddedTestExternal struct {
runtime.TypeMeta `yaml:",inline" json:",inline"`
ID string `yaml:"id,omitempty" json:"id,omitempty"`
Object runtime.RawExtension `yaml:"object,omitempty" json:"object,omitempty"`
EmptyObject runtime.RawExtension `yaml:"emptyObject,omitempty" json:"emptyObject,omitempty"`
}
@ -49,9 +51,11 @@ func TestEmbeddedObject(t *testing.T) {
outer := &EmbeddedTest{
TypeMeta: runtime.TypeMeta{Name: "outer"},
ID: "outer",
Object: runtime.EmbeddedObject{
&EmbeddedTest{
TypeMeta: runtime.TypeMeta{Name: "inner"},
ID: "inner",
},
},
}

View File

@ -26,8 +26,8 @@ import (
// TypeMeta is shared by all top level objects. The proper way to use it is to inline it in your type,
// like this:
// type MyAwesomeAPIObject struct {
// runtime.TypeMeta `yaml:",inline" json:",inline"`
// ... // other fields
// runtime.TypeMeta `yaml:",inline" json:",inline"`
// ... // other fields
// }
// func (*MyAwesomeAPIObject) IsAnAPIObject() {}
//
@ -35,12 +35,13 @@ import (
// your own with the same fields.
//
type TypeMeta struct {
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
CreationTimestamp util.Time `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"`
SelfLink string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"`
ResourceVersion string `json:"resourceVersion,omitempty" yaml:"resourceVersion,omitempty"`
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
}
// PluginBase is like TypeMeta, but it's intended for plugin objects that won't ever be encoded

View File

@ -25,6 +25,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
@ -44,7 +45,7 @@ func (*TestResource) IsAnAPIObject() {}
var scheme *runtime.Scheme
var codec runtime.Codec
var versioner = RuntimeVersionAdapter{runtime.NewTypeMetaResourceVersioner()}
var versioner = RuntimeVersionAdapter{meta.NewTypeMetaResourceVersioner()}
func init() {
scheme = runtime.NewScheme()