Merge pull request #18379 from deads2k/gv-newobject

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot 2015-12-13 13:33:16 -08:00
commit c458cd7bb7
17 changed files with 183 additions and 181 deletions

View File

@ -32,24 +32,24 @@ import (
func TestDeepCopyApiObjects(t *testing.T) { func TestDeepCopyApiObjects(t *testing.T) {
for i := 0; i < *fuzzIters; i++ { for i := 0; i < *fuzzIters; i++ {
for _, gv := range []unversioned.GroupVersion{testapi.Default.InternalGroupVersion(), *testapi.Default.GroupVersion()} { for _, version := range []unversioned.GroupVersion{testapi.Default.InternalGroupVersion(), *testapi.Default.GroupVersion()} {
f := apitesting.FuzzerFor(t, gv.String(), rand.NewSource(rand.Int63())) f := apitesting.FuzzerFor(t, version.String(), rand.NewSource(rand.Int63()))
for kind := range api.Scheme.KnownTypes(gv) { for kind := range api.Scheme.KnownTypes(version) {
doDeepCopyTest(t, gv.String(), kind, f) doDeepCopyTest(t, version.WithKind(kind), f)
} }
} }
} }
} }
func doDeepCopyTest(t *testing.T, version, kind string, f *fuzz.Fuzzer) { func doDeepCopyTest(t *testing.T, kind unversioned.GroupVersionKind, f *fuzz.Fuzzer) {
item, err := api.Scheme.New(version, kind) item, err := api.Scheme.New(kind)
if err != nil { if err != nil {
t.Fatalf("Could not create a %s: %s", kind, err) t.Fatalf("Could not create a %v: %s", kind, err)
} }
f.Fuzz(item) f.Fuzz(item)
itemCopy, err := api.Scheme.DeepCopy(item) itemCopy, err := api.Scheme.DeepCopy(item)
if err != nil { if err != nil {
t.Errorf("Could not deep copy a %s: %s", kind, err) t.Errorf("Could not deep copy a %v: %s", kind, err)
return return
} }
@ -60,9 +60,9 @@ func doDeepCopyTest(t *testing.T, version, kind string, f *fuzz.Fuzzer) {
func TestDeepCopySingleType(t *testing.T) { func TestDeepCopySingleType(t *testing.T) {
for i := 0; i < *fuzzIters; i++ { for i := 0; i < *fuzzIters; i++ {
for _, version := range []string{"", testapi.Default.GroupVersion().String()} { for _, version := range []unversioned.GroupVersion{testapi.Default.InternalGroupVersion(), *testapi.Default.GroupVersion()} {
f := apitesting.FuzzerFor(t, version, rand.NewSource(rand.Int63())) f := apitesting.FuzzerFor(t, version.String(), rand.NewSource(rand.Int63()))
doDeepCopyTest(t, version, "Pod", f) doDeepCopyTest(t, version.WithKind("Pod"), f)
} }
} }
} }

View File

@ -139,7 +139,7 @@ func TestList(t *testing.T) {
defer api.Scheme.Log(nil) defer api.Scheme.Log(nil)
kind := "List" kind := "List"
item, err := api.Scheme.New("", kind) item, err := api.Scheme.New(api.SchemeGroupVersion.WithKind(kind))
if err != nil { if err != nil {
t.Errorf("Couldn't make a %v? %v", kind, err) t.Errorf("Couldn't make a %v? %v", kind, err)
return return
@ -172,7 +172,7 @@ func TestRoundTripTypes(t *testing.T) {
} }
func doRoundTripTest(kind string, t *testing.T) { func doRoundTripTest(kind string, t *testing.T) {
item, err := api.Scheme.New(testapi.Default.InternalGroupVersion().String(), kind) item, err := api.Scheme.New(testapi.Default.InternalGroupVersion().WithKind(kind))
if err != nil { if err != nil {
t.Fatalf("Couldn't make a %v? %v", kind, err) t.Fatalf("Couldn't make a %v? %v", kind, err)
} }

View File

@ -104,9 +104,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
admit := a.group.Admit admit := a.group.Admit
context := a.group.Context context := a.group.Context
serverGroupVersion := a.group.GroupVersion optionsExternalVersion := a.group.GroupVersion
if a.group.ServerGroupVersion != nil { if a.group.OptionsExternalVersion != nil {
serverGroupVersion = *a.group.ServerGroupVersion optionsExternalVersion = *a.group.OptionsExternalVersion
} }
var resource, subresource string var resource, subresource string
@ -148,7 +148,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
} }
kind := fqKindToRegister.Kind kind := fqKindToRegister.Kind
versionedPtr, err := a.group.Creater.New(a.group.GroupVersion.String(), kind) versionedPtr, err := a.group.Creater.New(a.group.GroupVersion.WithKind(kind))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -218,14 +218,14 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if isLister { if isLister {
list := lister.NewList() list := lister.NewList()
listGVK, err := a.group.Typer.ObjectKind(list) listGVK, err := a.group.Typer.ObjectKind(list)
versionedListPtr, err := a.group.Creater.New(a.group.GroupVersion.String(), listGVK.Kind) versionedListPtr, err := a.group.Creater.New(a.group.GroupVersion.WithKind(listGVK.Kind))
if err != nil { if err != nil {
return nil, err return nil, err
} }
versionedList = indirectArbitraryPointer(versionedListPtr) versionedList = indirectArbitraryPointer(versionedListPtr)
} }
versionedListOptions, err := a.group.Creater.New(serverGroupVersion.String(), "ListOptions") versionedListOptions, err := a.group.Creater.New(optionsExternalVersion.WithKind("ListOptions"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -233,7 +233,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
var versionedDeleterObject interface{} var versionedDeleterObject interface{}
switch { switch {
case isGracefulDeleter: case isGracefulDeleter:
objectPtr, err := a.group.Creater.New(serverGroupVersion.String(), "DeleteOptions") objectPtr, err := a.group.Creater.New(optionsExternalVersion.WithKind("DeleteOptions"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -243,7 +243,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
gracefulDeleter = rest.GracefulDeleteAdapter{Deleter: deleter} gracefulDeleter = rest.GracefulDeleteAdapter{Deleter: deleter}
} }
versionedStatusPtr, err := a.group.Creater.New(serverGroupVersion.String(), "Status") versionedStatusPtr, err := a.group.Creater.New(optionsExternalVersion.WithKind("Status"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -263,9 +263,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
return nil, err return nil, err
} }
// TODO this should be a list of all the different external versions we can coerce into the internalKind // TODO this should be a list of all the different external versions we can coerce into the internalKind
getOptionsExternalKind = serverGroupVersion.WithKind(getOptionsInternalKind.Kind) getOptionsExternalKind = optionsExternalVersion.WithKind(getOptionsInternalKind.Kind)
versionedGetOptions, err = a.group.Creater.New(serverGroupVersion.String(), getOptionsInternalKind.Kind) versionedGetOptions, err = a.group.Creater.New(optionsExternalVersion.WithKind(getOptionsInternalKind.Kind))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -288,9 +288,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
return nil, err return nil, err
} }
// TODO this should be a list of all the different external versions we can coerce into the internalKind // TODO this should be a list of all the different external versions we can coerce into the internalKind
connectOptionsExternalKind = serverGroupVersion.WithKind(connectOptionsInternalKind.Kind) connectOptionsExternalKind = optionsExternalVersion.WithKind(connectOptionsInternalKind.Kind)
versionedConnectOptions, err = a.group.Creater.New(serverGroupVersion.String(), connectOptionsInternalKind.Kind) versionedConnectOptions, err = a.group.Creater.New(optionsExternalVersion.WithKind(connectOptionsInternalKind.Kind))
} }
} }

View File

@ -79,19 +79,20 @@ type Mux interface {
type APIGroupVersion struct { type APIGroupVersion struct {
Storage map[string]rest.Storage Storage map[string]rest.Storage
Root string Root string
// GroupVersion is the external group version
GroupVersion unversioned.GroupVersion GroupVersion unversioned.GroupVersion
// RequestInfoResolver is used to parse URLs for the legacy proxy handler. Don't use this for anything else // RequestInfoResolver is used to parse URLs for the legacy proxy handler. Don't use this for anything else
// TODO: refactor proxy handler to use sub resources // TODO: refactor proxy handler to use sub resources
RequestInfoResolver *RequestInfoResolver RequestInfoResolver *RequestInfoResolver
// ServerVersion controls the Kubernetes APIVersion used for common objects in the apiserver // OptionsExternalVersion controls the Kubernetes APIVersion used for common objects in the apiserver
// schema like api.Status, api.DeleteOptions, and unversioned.ListOptions. Other implementors may // schema like api.Status, api.DeleteOptions, and unversioned.ListOptions. Other implementors may
// define a version "v1beta1" but want to use the Kubernetes "v1" internal objects. If // define a version "v1beta1" but want to use the Kubernetes "v1" internal objects. If
// empty, defaults to Version. // empty, defaults to GroupVersion.
// TODO this seems suspicious. Is this actually just "unversioned" now? OptionsExternalVersion *unversioned.GroupVersion
ServerGroupVersion *unversioned.GroupVersion
Mapper meta.RESTMapper Mapper meta.RESTMapper

View File

@ -233,7 +233,7 @@ func handleInternal(storage map[string]rest.Storage, admissionControl admission.
group := template group := template
group.Root = "/" + grouplessPrefix group.Root = "/" + grouplessPrefix
group.GroupVersion = grouplessGroupVersion group.GroupVersion = grouplessGroupVersion
group.ServerGroupVersion = &grouplessGroupVersion group.OptionsExternalVersion = &grouplessGroupVersion
group.Codec = grouplessCodec group.Codec = grouplessCodec
if err := (&group).InstallREST(container); err != nil { if err := (&group).InstallREST(container); err != nil {
panic(fmt.Sprintf("unable to install container %s: %v", group.GroupVersion, err)) panic(fmt.Sprintf("unable to install container %s: %v", group.GroupVersion, err))
@ -245,7 +245,7 @@ func handleInternal(storage map[string]rest.Storage, admissionControl admission.
group := template group := template
group.Root = "/" + prefix group.Root = "/" + prefix
group.GroupVersion = testGroupVersion group.GroupVersion = testGroupVersion
group.ServerGroupVersion = &testGroupVersion group.OptionsExternalVersion = &testGroupVersion
group.Codec = codec group.Codec = codec
if err := (&group).InstallREST(container); err != nil { if err := (&group).InstallREST(container); err != nil {
panic(fmt.Sprintf("unable to install container %s: %v", group.GroupVersion, err)) panic(fmt.Sprintf("unable to install container %s: %v", group.GroupVersion, err))
@ -257,7 +257,7 @@ func handleInternal(storage map[string]rest.Storage, admissionControl admission.
group := template group := template
group.Root = "/" + prefix group.Root = "/" + prefix
group.GroupVersion = newGroupVersion group.GroupVersion = newGroupVersion
group.ServerGroupVersion = &newGroupVersion group.OptionsExternalVersion = &newGroupVersion
group.Codec = newCodec group.Codec = newCodec
if err := (&group).InstallREST(container); err != nil { if err := (&group).InstallREST(container); err != nil {
panic(fmt.Sprintf("unable to install container %s: %v", group.GroupVersion, err)) panic(fmt.Sprintf("unable to install container %s: %v", group.GroupVersion, err))
@ -2241,9 +2241,9 @@ func TestUpdateREST(t *testing.T) {
Context: requestContextMapper, Context: requestContextMapper,
Mapper: namespaceMapper, Mapper: namespaceMapper,
GroupVersion: newGroupVersion, GroupVersion: newGroupVersion,
ServerGroupVersion: &newGroupVersion, OptionsExternalVersion: &newGroupVersion,
Codec: newCodec, Codec: newCodec,
} }
} }
@ -2323,9 +2323,9 @@ func TestParentResourceIsRequired(t *testing.T) {
Context: requestContextMapper, Context: requestContextMapper,
Mapper: namespaceMapper, Mapper: namespaceMapper,
GroupVersion: newGroupVersion, GroupVersion: newGroupVersion,
ServerGroupVersion: &newGroupVersion, OptionsExternalVersion: &newGroupVersion,
Codec: newCodec, Codec: newCodec,
} }
container := restful.NewContainer() container := restful.NewContainer()
if err := group.InstallREST(container); err == nil { if err := group.InstallREST(container); err == nil {
@ -2352,9 +2352,9 @@ func TestParentResourceIsRequired(t *testing.T) {
Context: requestContextMapper, Context: requestContextMapper,
Mapper: namespaceMapper, Mapper: namespaceMapper,
GroupVersion: newGroupVersion, GroupVersion: newGroupVersion,
ServerGroupVersion: &newGroupVersion, OptionsExternalVersion: &newGroupVersion,
Codec: newCodec, Codec: newCodec,
} }
container = restful.NewContainer() container = restful.NewContainer()
if err := group.InstallREST(container); err != nil { if err := group.InstallREST(container); err != nil {

View File

@ -149,7 +149,7 @@ func getRequestOptions(req *restful.Request, scope RequestScope, internalKind, e
query = newQuery query = newQuery
} }
versioned, err := scope.Creater.New(externalKind.GroupVersion().String(), externalKind.Kind) versioned, err := scope.Creater.New(externalKind)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -152,24 +152,24 @@ func NewObjects(scheme ObjectScheme, decoder runtime.ObjectDecoder) ObjectRetrie
} }
} }
func (o objects) Kind(gvk unversioned.GroupVersionKind, name string) (runtime.Object, error) { func (o objects) Kind(kind unversioned.GroupVersionKind, name string) (runtime.Object, error) {
// TODO our test clients deal in internal versions. We need to plumb that knowledge down here // TODO our test clients deal in internal versions. We need to plumb that knowledge down here
// we might do this via an extra function to the scheme to allow getting internal group versions // we might do this via an extra function to the scheme to allow getting internal group versions
// I'm punting for now // I'm punting for now
gvk.Version = "" kind.Version = ""
empty, _ := o.scheme.New(gvk.GroupVersion().String(), gvk.Kind) empty, _ := o.scheme.New(kind)
nilValue := reflect.Zero(reflect.TypeOf(empty)).Interface().(runtime.Object) nilValue := reflect.Zero(reflect.TypeOf(empty)).Interface().(runtime.Object)
arr, ok := o.types[gvk.Kind] arr, ok := o.types[kind.Kind]
if !ok { if !ok {
if strings.HasSuffix(gvk.Kind, "List") { if strings.HasSuffix(kind.Kind, "List") {
itemKind := gvk.Kind[:len(gvk.Kind)-4] itemKind := kind.Kind[:len(kind.Kind)-4]
arr, ok := o.types[itemKind] arr, ok := o.types[itemKind]
if !ok { if !ok {
return empty, nil return empty, nil
} }
out, err := o.scheme.New(gvk.GroupVersion().String(), gvk.Kind) out, err := o.scheme.New(kind)
if err != nil { if err != nil {
return nilValue, err return nilValue, err
} }
@ -181,25 +181,25 @@ func (o objects) Kind(gvk unversioned.GroupVersionKind, name string) (runtime.Ob
} }
return out, nil return out, nil
} }
return nilValue, errors.NewNotFound(gvk.Kind, name) return nilValue, errors.NewNotFound(kind.Kind, name)
} }
index := o.last[gvk.Kind] index := o.last[kind.Kind]
if index >= len(arr) { if index >= len(arr) {
index = len(arr) - 1 index = len(arr) - 1
} }
if index < 0 { if index < 0 {
return nilValue, errors.NewNotFound(gvk.Kind, name) return nilValue, errors.NewNotFound(kind.Kind, name)
} }
out, err := o.scheme.Copy(arr[index]) out, err := o.scheme.Copy(arr[index])
if err != nil { if err != nil {
return nilValue, err return nilValue, err
} }
o.last[gvk.Kind] = index + 1 o.last[kind.Kind] = index + 1
if status, ok := out.(*unversioned.Status); ok { if status, ok := out.(*unversioned.Status); ok {
if status.Details != nil { if status.Details != nil {
status.Details.Kind = gvk.Kind status.Details.Kind = kind.Kind
} }
if status.Status != unversioned.StatusSuccess { if status.Status != unversioned.StatusSuccess {
return nilValue, &errors.StatusError{ErrStatus: *status} return nilValue, &errors.StatusError{ErrStatus: *status}

View File

@ -26,36 +26,36 @@ import (
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
) )
func (s *Scheme) DecodeToVersionedObject(data []byte) (interface{}, string, string, error) { func (s *Scheme) DecodeToVersionedObject(data []byte) (interface{}, unversioned.GroupVersionKind, error) {
gvk, err := s.DataKind(data) kind, err := s.DataKind(data)
if err != nil { if err != nil {
return nil, "", "", err return nil, unversioned.GroupVersionKind{}, err
} }
internalGV, exists := s.InternalVersions[gvk.Group] internalGV, exists := s.InternalVersions[kind.Group]
if !exists { if !exists {
return nil, "", "", fmt.Errorf("no internalVersion specified for %v", gvk) return nil, unversioned.GroupVersionKind{}, fmt.Errorf("no internalVersion specified for %v", kind)
} }
if len(gvk.Group) == 0 && len(internalGV.Group) != 0 { if len(kind.Group) == 0 && len(internalGV.Group) != 0 {
return nil, "", "", fmt.Errorf("group not set in '%s'", string(data)) return nil, unversioned.GroupVersionKind{}, fmt.Errorf("group not set in '%s'", string(data))
} }
if len(gvk.Version) == 0 && len(internalGV.Version) != 0 { if len(kind.Version) == 0 && len(internalGV.Version) != 0 {
return nil, "", "", fmt.Errorf("version not set in '%s'", string(data)) return nil, unversioned.GroupVersionKind{}, fmt.Errorf("version not set in '%s'", string(data))
} }
if gvk.Kind == "" { if kind.Kind == "" {
return nil, "", "", fmt.Errorf("kind not set in '%s'", string(data)) return nil, unversioned.GroupVersionKind{}, fmt.Errorf("kind not set in '%s'", string(data))
} }
obj, err := s.NewObject(gvk.GroupVersion().String(), gvk.Kind) obj, err := s.NewObject(kind)
if err != nil { if err != nil {
return nil, "", "", err return nil, unversioned.GroupVersionKind{}, err
} }
if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(obj); err != nil { if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(obj); err != nil {
return nil, "", "", err return nil, unversioned.GroupVersionKind{}, err
} }
return obj, gvk.GroupVersion().String(), gvk.Kind, nil return obj, kind, nil
} }
// Decode converts a JSON string back into a pointer to an api object. // Decode converts a JSON string back into a pointer to an api object.
@ -74,8 +74,8 @@ func (s *Scheme) Decode(data []byte) (interface{}, error) {
// set unless version is also "". // set unless version is also "".
// a GroupVersion with .IsEmpty() == true is means "use the internal version for // a GroupVersion with .IsEmpty() == true is means "use the internal version for
// the object's group" // the object's group"
func (s *Scheme) DecodeToVersion(data []byte, gv unversioned.GroupVersion) (interface{}, error) { func (s *Scheme) DecodeToVersion(data []byte, targetVersion unversioned.GroupVersion) (interface{}, error) {
obj, sourceVersion, kind, err := s.DecodeToVersionedObject(data) obj, sourceKind, err := s.DecodeToVersionedObject(data)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -84,28 +84,23 @@ func (s *Scheme) DecodeToVersion(data []byte, gv unversioned.GroupVersion) (inte
return nil, err return nil, err
} }
sourceGV, err := unversioned.ParseGroupVersion(sourceVersion) // if the targetVersion is empty, then we want the internal version, but the internal version varies by
if err != nil {
return nil, err
}
// if the gv is empty, then we want the internal version, but the internal version varies by
// group. We can lookup the group now because we have knowledge of the group // group. We can lookup the group now because we have knowledge of the group
if gv.IsEmpty() { if targetVersion.IsEmpty() {
exists := false exists := false
gv, exists = s.InternalVersions[sourceGV.Group] targetVersion, exists = s.InternalVersions[sourceKind.Group]
if !exists { if !exists {
return nil, fmt.Errorf("no internalVersion specified for %v", gv) return nil, fmt.Errorf("no internalVersion specified for %v", targetVersion)
} }
} }
// Convert if needed. // Convert if needed.
if gv != sourceGV { if targetVersion != sourceKind.GroupVersion() {
objOut, err := s.NewObject(gv.String(), kind) objOut, err := s.NewObject(targetVersion.WithKind(sourceKind.Kind))
if err != nil { if err != nil {
return nil, err return nil, err
} }
flags, meta := s.generateConvertMeta(sourceGV, gv, obj) flags, meta := s.generateConvertMeta(sourceKind.GroupVersion(), targetVersion, obj)
if err := s.converter.Convert(obj, objOut, flags, meta); err != nil { if err := s.converter.Convert(obj, objOut, flags, meta); err != nil {
return nil, err return nil, err
} }
@ -134,28 +129,28 @@ func (s *Scheme) DecodeIntoWithSpecifiedVersionKind(data []byte, obj interface{}
if len(data) == 0 { if len(data) == 0 {
return errors.New("empty input") return errors.New("empty input")
} }
dataGVK, err := s.DataKind(data) dataKind, err := s.DataKind(data)
if err != nil { if err != nil {
return err return err
} }
if len(dataGVK.Group) == 0 { if len(dataKind.Group) == 0 {
dataGVK.Group = requestedGVK.Group dataKind.Group = requestedGVK.Group
} }
if len(dataGVK.Version) == 0 { if len(dataKind.Version) == 0 {
dataGVK.Version = requestedGVK.Version dataKind.Version = requestedGVK.Version
} }
if len(dataGVK.Kind) == 0 { if len(dataKind.Kind) == 0 {
dataGVK.Kind = requestedGVK.Kind dataKind.Kind = requestedGVK.Kind
} }
if len(requestedGVK.Group) > 0 && requestedGVK.Group != dataGVK.Group { if len(requestedGVK.Group) > 0 && requestedGVK.Group != dataKind.Group {
return errors.New(fmt.Sprintf("The fully qualified kind in the data (%v) does not match the specified apiVersion(%v)", dataGVK, requestedGVK)) return errors.New(fmt.Sprintf("The fully qualified kind in the data (%v) does not match the specified apiVersion(%v)", dataKind, requestedGVK))
} }
if len(requestedGVK.Version) > 0 && requestedGVK.Version != dataGVK.Version { if len(requestedGVK.Version) > 0 && requestedGVK.Version != dataKind.Version {
return errors.New(fmt.Sprintf("The fully qualified kind in the data (%v) does not match the specified apiVersion(%v)", dataGVK, requestedGVK)) return errors.New(fmt.Sprintf("The fully qualified kind in the data (%v) does not match the specified apiVersion(%v)", dataKind, requestedGVK))
} }
if len(requestedGVK.Kind) > 0 && requestedGVK.Kind != dataGVK.Kind { if len(requestedGVK.Kind) > 0 && requestedGVK.Kind != dataKind.Kind {
return errors.New(fmt.Sprintf("The fully qualified kind in the data (%v) does not match the specified apiVersion(%v)", dataGVK, requestedGVK)) return errors.New(fmt.Sprintf("The fully qualified kind in the data (%v) does not match the specified apiVersion(%v)", dataKind, requestedGVK))
} }
objGVK, err := s.ObjectKind(obj) objGVK, err := s.ObjectKind(obj)
@ -164,24 +159,24 @@ func (s *Scheme) DecodeIntoWithSpecifiedVersionKind(data []byte, obj interface{}
} }
// Assume objects with unset fields are being unmarshalled into the // Assume objects with unset fields are being unmarshalled into the
// correct type. // correct type.
if len(dataGVK.Group) == 0 { if len(dataKind.Group) == 0 {
dataGVK.Group = objGVK.Group dataKind.Group = objGVK.Group
} }
if len(dataGVK.Version) == 0 { if len(dataKind.Version) == 0 {
dataGVK.Version = objGVK.Version dataKind.Version = objGVK.Version
} }
if len(dataGVK.Kind) == 0 { if len(dataKind.Kind) == 0 {
dataGVK.Kind = objGVK.Kind dataKind.Kind = objGVK.Kind
} }
external, err := s.NewObject(dataGVK.GroupVersion().String(), dataGVK.Kind) external, err := s.NewObject(dataKind)
if err != nil { if err != nil {
return err return err
} }
if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(external); err != nil { if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(external); err != nil {
return err return err
} }
flags, meta := s.generateConvertMeta(dataGVK.GroupVersion(), objGVK.GroupVersion(), external) flags, meta := s.generateConvertMeta(dataKind.GroupVersion(), objGVK.GroupVersion(), external)
if err := s.converter.Convert(external, obj, flags, meta); err != nil { if err := s.converter.Convert(external, obj, flags, meta); err != nil {
return err return err
} }

View File

@ -62,14 +62,14 @@ func (s *Scheme) EncodeToVersion(obj interface{}, destVersion string) (data []by
return buff.Bytes(), nil return buff.Bytes(), nil
} }
func (s *Scheme) EncodeToVersionStream(obj interface{}, destVersion string, stream io.Writer) error { func (s *Scheme) EncodeToVersionStream(obj interface{}, destGroupVersionString string, stream io.Writer) error {
obj = maybeCopy(obj) obj = maybeCopy(obj)
v, _ := EnforcePtr(obj) // maybeCopy guarantees a pointer v, _ := EnforcePtr(obj) // maybeCopy guarantees a pointer
// Don't encode an object defined in the unversioned package, unless if the // Don't encode an object defined in the unversioned package, unless if the
// destVersion is v1, encode it to v1 for backward compatibility. // destGroupVersionString is v1, encode it to v1 for backward compatibility.
pkg := path.Base(v.Type().PkgPath()) pkg := path.Base(v.Type().PkgPath())
if pkg == "unversioned" && destVersion != "v1" { if pkg == "unversioned" && destGroupVersionString != "v1" {
// TODO: convert this to streaming too // TODO: convert this to streaming too
data, err := s.encodeUnversionedObject(obj) data, err := s.encodeUnversionedObject(obj)
if err != nil { if err != nil {
@ -80,21 +80,26 @@ func (s *Scheme) EncodeToVersionStream(obj interface{}, destVersion string, stre
} }
if _, registered := s.typeToGVK[v.Type()]; !registered { if _, registered := s.typeToGVK[v.Type()]; !registered {
return fmt.Errorf("type %v is not registered for %q and it will be impossible to Decode it, therefore Encode will refuse to encode it.", v.Type(), destVersion) return fmt.Errorf("type %v is not registered for %q and it will be impossible to Decode it, therefore Encode will refuse to encode it.", v.Type(), destGroupVersionString)
} }
objGVK, err := s.ObjectKind(obj) objKind, err := s.ObjectKind(obj)
if err != nil {
return err
}
destVersion, err := unversioned.ParseGroupVersion(destGroupVersionString)
if err != nil { if err != nil {
return err return err
} }
// Perform a conversion if necessary. // Perform a conversion if necessary.
if objGVK.GroupVersion().String() != destVersion { if objKind.GroupVersion() != destVersion {
objOut, err := s.NewObject(destVersion, objGVK.Kind) objOut, err := s.NewObject(destVersion.WithKind(objKind.Kind))
if err != nil { if err != nil {
return err return err
} }
flags, meta := s.generateConvertMeta(objGVK.GroupVersion(), unversioned.ParseGroupVersionOrDie(destVersion), obj) flags, meta := s.generateConvertMeta(objKind.GroupVersion(), destVersion, obj)
err = s.converter.Convert(obj, objOut, flags, meta) err = s.converter.Convert(obj, objOut, flags, meta)
if err != nil { if err != nil {
return err return err
@ -106,11 +111,11 @@ func (s *Scheme) EncodeToVersionStream(obj interface{}, destVersion string, stre
if err != nil { if err != nil {
return err return err
} }
objGVK.Kind = newGroupVersionKind.Kind objKind.Kind = newGroupVersionKind.Kind
} }
// Version and Kind should be set on the wire. // Version and Kind should be set on the wire.
err = s.SetVersionAndKind(destVersion, objGVK.Kind, obj) err = s.SetVersionAndKind(destVersion.String(), objKind.Kind, obj)
if err != nil { if err != nil {
return err return err
} }

View File

@ -163,18 +163,12 @@ func (s *Scheme) KnownTypes(gv unversioned.GroupVersion) map[string]reflect.Type
// NewObject returns a new object of the given version and name, // NewObject returns a new object of the given version and name,
// or an error if it hasn't been registered. // or an error if it hasn't been registered.
func (s *Scheme) NewObject(gvString, kind string) (interface{}, error) { func (s *Scheme) NewObject(kind unversioned.GroupVersionKind) (interface{}, error) {
gv, err := unversioned.ParseGroupVersion(gvString) if t, exists := s.gvkToType[kind]; exists {
if err != nil {
return nil, err
}
gvk := gv.WithKind(kind)
if t, exists := s.gvkToType[gvk]; exists {
return reflect.New(t).Interface(), nil return reflect.New(t).Interface(), nil
} }
return nil, &notRegisteredErr{gvk: gvk} return nil, &notRegisteredErr{gvk: kind}
} }
// AddConversionFuncs adds functions to the list of conversion functions. The given // AddConversionFuncs adds functions to the list of conversion functions. The given
@ -326,7 +320,7 @@ func (s *Scheme) Convert(in, out interface{}) error {
// ConvertToVersion attempts to convert an input object to its matching Kind in another // ConvertToVersion attempts to convert an input object to its matching Kind in another
// version within this scheme. Will return an error if the provided version does not // version within this scheme. Will return an error if the provided version does not
// contain the inKind (or a mapping by name defined with AddKnownTypeWithName). // contain the inKind (or a mapping by name defined with AddKnownTypeWithName).
func (s *Scheme) ConvertToVersion(in interface{}, outVersion string) (interface{}, error) { func (s *Scheme) ConvertToVersion(in interface{}, outGroupVersionString string) (interface{}, error) {
t := reflect.TypeOf(in) t := reflect.TypeOf(in)
if t.Kind() != reflect.Ptr { if t.Kind() != reflect.Ptr {
return nil, fmt.Errorf("only pointer types may be converted: %v", t) return nil, fmt.Errorf("only pointer types may be converted: %v", t)
@ -338,25 +332,25 @@ func (s *Scheme) ConvertToVersion(in interface{}, outVersion string) (interface{
gvks, ok := s.typeToGVK[t] gvks, ok := s.typeToGVK[t]
if !ok { if !ok {
return nil, fmt.Errorf("%v cannot be converted into version %q", t, outVersion) return nil, fmt.Errorf("%v cannot be converted into version %q", t, outGroupVersionString)
} }
outGV, err := unversioned.ParseGroupVersion(outVersion) outVersion, err := unversioned.ParseGroupVersion(outGroupVersionString)
if err != nil { if err != nil {
return nil, err return nil, err
} }
outGVK := outGV.WithKind(gvks[0].Kind) outKind := outVersion.WithKind(gvks[0].Kind)
inGVK, err := s.ObjectKind(in) inKind, err := s.ObjectKind(in)
if err != nil { if err != nil {
return nil, err return nil, err
} }
out, err := s.NewObject(outGV.String(), outGVK.Kind) out, err := s.NewObject(outKind)
if err != nil { if err != nil {
return nil, err return nil, err
} }
flags, meta := s.generateConvertMeta(inGVK.GroupVersion(), outGV, in) flags, meta := s.generateConvertMeta(inKind.GroupVersion(), outVersion, in)
if err := s.converter.Convert(in, out, flags, meta); err != nil { if err := s.converter.Convert(in, out, flags, meta); err != nil {
return nil, err return nil, err
} }
@ -367,7 +361,7 @@ func (s *Scheme) ConvertToVersion(in interface{}, outVersion string) (interface{
// return nil, err // return nil, err
// } // }
// ======= // =======
if err := s.SetVersionAndKind(outGV.String(), outGVK.Kind, out); err != nil { if err := s.SetVersionAndKind(outVersion.String(), outKind.Kind, out); err != nil {
return nil, err return nil, err
// >>>>>>> Update ObjectTyper to GroupVersion // >>>>>>> Update ObjectTyper to GroupVersion
} }

View File

@ -73,7 +73,7 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) {
var versionedObject interface{} var versionedObject interface{}
if vo, _, _, err := api.Scheme.Raw().DecodeToVersionedObject(data); err == nil { if vo, _, err := api.Scheme.Raw().DecodeToVersionedObject(data); err == nil {
versionedObject = vo versionedObject = vo
} }
return &Info{ return &Info{

View File

@ -1002,7 +1002,7 @@ func (m *Master) thirdpartyapi(group, kind, version string) *apiserver.APIGroupV
strings.ToLower(kind) + "s": resourceStorage, strings.ToLower(kind) + "s": resourceStorage,
} }
serverGroupVersion := latest.GroupOrDie("").GroupVersion optionsExternalVersion := latest.GroupOrDie("").GroupVersion
return &apiserver.APIGroupVersion{ return &apiserver.APIGroupVersion{
Root: apiRoot, Root: apiRoot,
@ -1013,11 +1013,11 @@ func (m *Master) thirdpartyapi(group, kind, version string) *apiserver.APIGroupV
Convertor: api.Scheme, Convertor: api.Scheme,
Typer: api.Scheme, Typer: api.Scheme,
Mapper: thirdpartyresourcedata.NewMapper(latest.GroupOrDie("extensions").RESTMapper, kind, version, group), Mapper: thirdpartyresourcedata.NewMapper(latest.GroupOrDie("extensions").RESTMapper, kind, version, group),
Codec: thirdpartyresourcedata.NewCodec(latest.GroupOrDie("extensions").Codec, kind), Codec: thirdpartyresourcedata.NewCodec(latest.GroupOrDie("extensions").Codec, kind),
Linker: latest.GroupOrDie("extensions").SelfLinker, Linker: latest.GroupOrDie("extensions").SelfLinker,
Storage: storage, Storage: storage,
ServerGroupVersion: &serverGroupVersion, OptionsExternalVersion: &optionsExternalVersion,
Context: m.requestContextMapper, Context: m.requestContextMapper,
@ -1092,7 +1092,7 @@ func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion {
} }
extensionsGroup := latest.GroupOrDie("extensions") extensionsGroup := latest.GroupOrDie("extensions")
serverGroupVersion := latest.GroupOrDie("").GroupVersion optionsExternalVersion := latest.GroupOrDie("").GroupVersion
return &apiserver.APIGroupVersion{ return &apiserver.APIGroupVersion{
Root: m.apiGroupPrefix, Root: m.apiGroupPrefix,
@ -1102,12 +1102,12 @@ func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion {
Convertor: api.Scheme, Convertor: api.Scheme,
Typer: api.Scheme, Typer: api.Scheme,
Mapper: extensionsGroup.RESTMapper, Mapper: extensionsGroup.RESTMapper,
Codec: extensionsGroup.Codec, Codec: extensionsGroup.Codec,
Linker: extensionsGroup.SelfLinker, Linker: extensionsGroup.SelfLinker,
Storage: storage, Storage: storage,
GroupVersion: extensionsGroup.GroupVersion, GroupVersion: extensionsGroup.GroupVersion,
ServerGroupVersion: &serverGroupVersion, OptionsExternalVersion: &optionsExternalVersion,
Admit: m.admissionControl, Admit: m.admissionControl,
Context: m.requestContextMapper, Context: m.requestContextMapper,

View File

@ -290,19 +290,19 @@ type thirdPartyResourceDataCreator struct {
delegate runtime.ObjectCreater delegate runtime.ObjectCreater
} }
func (t *thirdPartyResourceDataCreator) New(groupVersion, kind string) (out runtime.Object, err error) { func (t *thirdPartyResourceDataCreator) New(kind unversioned.GroupVersionKind) (out runtime.Object, err error) {
switch kind { switch kind.Kind {
case "ThirdPartyResourceData": case "ThirdPartyResourceData":
if apiutil.GetGroupVersion(t.group, t.version) != groupVersion { if apiutil.GetGroupVersion(t.group, t.version) != kind.GroupVersion().String() {
return nil, fmt.Errorf("unknown version %s for kind %s", groupVersion, kind) return nil, fmt.Errorf("unknown kind %v", kind)
} }
return &extensions.ThirdPartyResourceData{}, nil return &extensions.ThirdPartyResourceData{}, nil
case "ThirdPartyResourceDataList": case "ThirdPartyResourceDataList":
if apiutil.GetGroupVersion(t.group, t.version) != groupVersion { if apiutil.GetGroupVersion(t.group, t.version) != kind.GroupVersion().String() {
return nil, fmt.Errorf("unknown version %s for kind %s", groupVersion, kind) return nil, fmt.Errorf("unknown kind %v", kind)
} }
return &extensions.ThirdPartyResourceDataList{}, nil return &extensions.ThirdPartyResourceDataList{}, nil
default: default:
return t.delegate.New(groupVersion, kind) return t.delegate.New(kind)
} }
} }

View File

@ -140,35 +140,31 @@ func TestCreater(t *testing.T) {
creater := NewObjectCreator("creater group", "creater version", api.Scheme) creater := NewObjectCreator("creater group", "creater version", api.Scheme)
tests := []struct { tests := []struct {
name string name string
version string kind unversioned.GroupVersionKind
kind string
expectedObj runtime.Object expectedObj runtime.Object
expectErr bool expectErr bool
}{ }{
{ {
name: "valid ThirdPartyResourceData creation", name: "valid ThirdPartyResourceData creation",
version: "creater group/creater version", kind: unversioned.GroupVersionKind{Group: "creater group", Version: "creater version", Kind: "ThirdPartyResourceData"},
kind: "ThirdPartyResourceData",
expectedObj: &extensions.ThirdPartyResourceData{}, expectedObj: &extensions.ThirdPartyResourceData{},
expectErr: false, expectErr: false,
}, },
{ {
name: "invalid ThirdPartyResourceData creation", name: "invalid ThirdPartyResourceData creation",
version: "invalid version", kind: unversioned.GroupVersionKind{Version: "invalid version", Kind: "ThirdPartyResourceData"},
kind: "ThirdPartyResourceData",
expectedObj: nil, expectedObj: nil,
expectErr: true, expectErr: true,
}, },
{ {
name: "valid ListOptions creation", name: "valid ListOptions creation",
version: "v1", kind: unversioned.GroupVersionKind{Version: "v1", Kind: "ListOptions"},
kind: "ListOptions",
expectedObj: &v1.ListOptions{}, expectedObj: &v1.ListOptions{},
expectErr: false, expectErr: false,
}, },
} }
for _, test := range tests { for _, test := range tests {
out, err := creater.New(test.version, test.kind) out, err := creater.New(test.kind)
if err != nil && !test.expectErr { if err != nil && !test.expectErr {
t.Errorf("[%s] unexpected error: %v", test.name, err) t.Errorf("[%s] unexpected error: %v", test.name, err)
} }

View File

@ -90,12 +90,12 @@ func (g *conversionGenerator) AddImport(pkg string) string {
func (g *conversionGenerator) GenerateConversionsForType(gv unversioned.GroupVersion, reflection reflect.Type) error { func (g *conversionGenerator) GenerateConversionsForType(gv unversioned.GroupVersion, reflection reflect.Type) error {
kind := reflection.Name() kind := reflection.Name()
// TODO this is equivalent to what it did before, but it needs to be fixed for the proper group // TODO this is equivalent to what it did before, but it needs to be fixed for the proper group
internalGV, exists := g.scheme.InternalVersions[gv.Group] internalVersion, exists := g.scheme.InternalVersions[gv.Group]
if !exists { if !exists {
return fmt.Errorf("no internal version for %v", gv) return fmt.Errorf("no internal version for %v", gv)
} }
internalObj, err := g.scheme.NewObject(internalGV.String(), kind) internalObj, err := g.scheme.NewObject(internalVersion.WithKind(kind))
if err != nil { if err != nil {
return fmt.Errorf("cannot create an object of type %v in internal version", kind) return fmt.Errorf("cannot create an object of type %v in internal version", kind)
} }

View File

@ -109,7 +109,7 @@ type ObjectTyper interface {
// ObjectCreater contains methods for instantiating an object by kind and version. // ObjectCreater contains methods for instantiating an object by kind and version.
type ObjectCreater interface { type ObjectCreater interface {
New(version, kind string) (out Object, err error) New(kind unversioned.GroupVersionKind) (out Object, err error)
} }
// ObjectCopier duplicates an object. // ObjectCopier duplicates an object.

View File

@ -70,14 +70,18 @@ func (self *Scheme) embeddedObjectToRawExtension(in *EmbeddedObject, out *RawExt
} }
// Figure out the type and kind of the output object. // Figure out the type and kind of the output object.
_, outVersion, scheme := self.fromScope(s) _, outGroupVersionString, scheme := self.fromScope(s)
gvk, err := scheme.raw.ObjectKind(in.Object) objKind, err := scheme.raw.ObjectKind(in.Object)
if err != nil {
return err
}
outVersion, err := unversioned.ParseGroupVersion(outGroupVersionString)
if err != nil { if err != nil {
return err return err
} }
// Manufacture an object of this type and kind. // Manufacture an object of this type and kind.
outObj, err := scheme.New(outVersion, gvk.Kind) outObj, err := scheme.New(outVersion.WithKind(objKind.Kind))
if err != nil { if err != nil {
return err return err
} }
@ -90,7 +94,7 @@ func (self *Scheme) embeddedObjectToRawExtension(in *EmbeddedObject, out *RawExt
// Copy the kind field into the output object. // Copy the kind field into the output object.
err = s.Convert( err = s.Convert(
&emptyPlugin{PluginBase: PluginBase{Kind: gvk.Kind}}, &emptyPlugin{PluginBase: PluginBase{Kind: objKind.Kind}},
outObj, outObj,
conversion.SourceToDest|conversion.IgnoreMissingFields|conversion.AllowDifferentFieldTypeNames, conversion.SourceToDest|conversion.IgnoreMissingFields|conversion.AllowDifferentFieldTypeNames,
) )
@ -98,7 +102,7 @@ func (self *Scheme) embeddedObjectToRawExtension(in *EmbeddedObject, out *RawExt
return err return err
} }
// Because we provide the correct version, EncodeToVersion will not attempt a conversion. // Because we provide the correct version, EncodeToVersion will not attempt a conversion.
raw, err := scheme.EncodeToVersion(outObj, outVersion) raw, err := scheme.EncodeToVersion(outObj, outVersion.String())
if err != nil { if err != nil {
// TODO: if this fails, create an Unknown-- maybe some other // TODO: if this fails, create an Unknown-- maybe some other
// component will understand it. // component will understand it.
@ -117,15 +121,23 @@ func (self *Scheme) rawExtensionToEmbeddedObject(in *RawExtension, out *Embedded
return nil return nil
} }
// Figure out the type and kind of the output object. // Figure out the type and kind of the output object.
inVersion, outVersion, scheme := self.fromScope(s) inGroupVersionString, outGroupVersionString, scheme := self.fromScope(s)
gvk, err := scheme.raw.DataKind(in.RawJSON) dataKind, err := scheme.raw.DataKind(in.RawJSON)
if err != nil {
return err
}
inVersion, err := unversioned.ParseGroupVersion(inGroupVersionString)
if err != nil {
return err
}
outVersion, err := unversioned.ParseGroupVersion(outGroupVersionString)
if err != nil { if err != nil {
return err return err
} }
// We have to make this object ourselves because we don't store the version field for // We have to make this object ourselves because we don't store the version field for
// plugin objects. // plugin objects.
inObj, err := scheme.New(inVersion, gvk.Kind) inObj, err := scheme.New(inVersion.WithKind(dataKind.Kind))
if err != nil { if err != nil {
return err return err
} }
@ -136,7 +148,7 @@ func (self *Scheme) rawExtensionToEmbeddedObject(in *RawExtension, out *Embedded
} }
// Make the desired internal version, and do the conversion. // Make the desired internal version, and do the conversion.
outObj, err := scheme.New(outVersion, gvk.Kind) outObj, err := scheme.New(outVersion.WithKind(dataKind.Kind))
if err != nil { if err != nil {
return err return err
} }
@ -209,14 +221,14 @@ func (self *Scheme) rawExtensionToRuntimeObjectArray(in *[]RawExtension, out *[]
for i := range src { for i := range src {
data := src[i].RawJSON data := src[i].RawJSON
gvk, err := scheme.raw.DataKind(data) dataKind, err := scheme.raw.DataKind(data)
if err != nil { if err != nil {
return err return err
} }
dest[i] = &Unknown{ dest[i] = &Unknown{
TypeMeta: TypeMeta{ TypeMeta: TypeMeta{
APIVersion: gvk.GroupVersion().String(), APIVersion: dataKind.GroupVersion().String(),
Kind: gvk.Kind, Kind: dataKind.Kind,
}, },
RawJSON: data, RawJSON: data,
} }
@ -306,10 +318,9 @@ func (s *Scheme) Recognizes(gvk unversioned.GroupVersionKind) bool {
return s.raw.Recognizes(gvk) return s.raw.Recognizes(gvk)
} }
// New returns a new API object of the given version ("" for internal // New returns a new API object of the given kind, or an error if it hasn't been registered.
// representation) and name, or an error if it hasn't been registered. func (s *Scheme) New(kind unversioned.GroupVersionKind) (Object, error) {
func (s *Scheme) New(versionName, typeName string) (Object, error) { obj, err := s.raw.NewObject(kind)
obj, err := s.raw.NewObject(versionName, typeName)
if err != nil { if err != nil {
return nil, err return nil, err
} }