hack up queryToObject to continue to work as it used to

This commit is contained in:
deads2k 2015-11-18 09:26:29 -05:00
parent 68b0572974
commit e0b7f52633
4 changed files with 55 additions and 27 deletions

View File

@ -149,15 +149,31 @@ func getRequestOptions(req *restful.Request, scope RequestScope, kind string, su
newQuery[subpathKey] = []string{req.PathParameter("path")} newQuery[subpathKey] = []string{req.PathParameter("path")}
query = newQuery query = newQuery
} }
versioned, err := scope.Creater.New(scope.ServerAPIVersion, kind)
// TODO Options a mess. Basically the intent is:
// 1. try to decode using the expected external GroupVersion
// 2. if that fails, fall back to the old external serialization being used before, which was
// "v1" and decode into the unversioned/legacykube group
gvString := scope.APIVersion
internalGVString := scope.InternalVersion.String()
versioned, err := scope.Creater.New(gvString, kind)
if err != nil { if err != nil {
// programmer error gvString = "v1"
return nil, err internalGVString = ""
var secondErr error
versioned, secondErr = scope.Creater.New(gvString, kind)
// if we have an error, return the original failure
if secondErr != nil {
return nil, err
}
} }
if err := scope.Codec.DecodeParametersInto(query, versioned); err != nil { if err := scope.Codec.DecodeParametersInto(query, versioned); err != nil {
return nil, errors.NewBadRequest(err.Error()) return nil, errors.NewBadRequest(err.Error())
} }
out, err := scope.Convertor.ConvertToVersion(versioned, scope.InternalVersion.String()) out, err := scope.Convertor.ConvertToVersion(versioned, internalGVString)
if err != nil { if err != nil {
// programmer error // programmer error
return nil, err return nil, err

View File

@ -38,7 +38,7 @@ import (
type ObjectRetriever interface { type ObjectRetriever interface {
// Kind should return a resource or a list of resources (depending on the provided kind and // Kind should return a resource or a list of resources (depending on the provided kind and
// name). It should return an error if the caller should communicate an error to the server. // name). It should return an error if the caller should communicate an error to the server.
Kind(kind, name string) (runtime.Object, error) Kind(gvk unversioned.GroupVersionKind, name string) (runtime.Object, error)
// Add adds a runtime object for test purposes into this object. // Add adds a runtime object for test purposes into this object.
Add(runtime.Object) error Add(runtime.Object) error
} }
@ -59,23 +59,29 @@ type ObjectScheme interface {
func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc { func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {
return func(action Action) (bool, runtime.Object, error) { return func(action Action) (bool, runtime.Object, error) {
_, kind, err := mapper.VersionAndKindForResource(action.GetResource()) gvString, kind, err := mapper.VersionAndKindForResource(action.GetResource())
if err != nil { if err != nil {
return false, nil, fmt.Errorf("unrecognized action %s: %v", action.GetResource(), err) return false, nil, fmt.Errorf("unrecognized action %s: %v", action.GetResource(), err)
} }
gv, err := unversioned.ParseGroupVersion(gvString)
if err != nil {
return false, nil, err
}
gvk := gv.WithKind(kind)
// TODO: have mapper return a Kind for a subresource? // TODO: have mapper return a Kind for a subresource?
switch castAction := action.(type) { switch castAction := action.(type) {
case ListAction: case ListAction:
resource, err := o.Kind(kind+"List", "") gvk.Kind += "List"
resource, err := o.Kind(gvk, "")
return true, resource, err return true, resource, err
case GetAction: case GetAction:
resource, err := o.Kind(kind, castAction.GetName()) resource, err := o.Kind(gvk, castAction.GetName())
return true, resource, err return true, resource, err
case DeleteAction: case DeleteAction:
resource, err := o.Kind(kind, castAction.GetName()) resource, err := o.Kind(gvk, castAction.GetName())
return true, resource, err return true, resource, err
case CreateAction: case CreateAction:
@ -83,7 +89,7 @@ func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {
if err != nil { if err != nil {
return true, nil, err return true, nil, err
} }
resource, err := o.Kind(kind, meta.Name) resource, err := o.Kind(gvk, meta.Name)
return true, resource, err return true, resource, err
case UpdateAction: case UpdateAction:
@ -91,7 +97,7 @@ func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {
if err != nil { if err != nil {
return true, nil, err return true, nil, err
} }
resource, err := o.Kind(kind, meta.Name) resource, err := o.Kind(gvk, meta.Name)
return true, resource, err return true, resource, err
default: default:
@ -151,19 +157,24 @@ func NewObjects(scheme ObjectScheme, decoder runtime.ObjectDecoder) ObjectRetrie
} }
} }
func (o objects) Kind(kind, name string) (runtime.Object, error) { func (o objects) Kind(gvk unversioned.GroupVersionKind, name string) (runtime.Object, error) {
empty, _ := o.scheme.New("", kind) // 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
// I'm punting for now
gvk.Version = ""
empty, _ := o.scheme.New(gvk.GroupVersion().String(), gvk.Kind)
nilValue := reflect.Zero(reflect.TypeOf(empty)).Interface().(runtime.Object) nilValue := reflect.Zero(reflect.TypeOf(empty)).Interface().(runtime.Object)
arr, ok := o.types[kind] arr, ok := o.types[gvk.Kind]
if !ok { if !ok {
if strings.HasSuffix(kind, "List") { if strings.HasSuffix(gvk.Kind, "List") {
itemKind := kind[:len(kind)-4] itemKind := gvk.Kind[:len(gvk.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("", kind) out, err := o.scheme.New(gvk.GroupVersion().String(), gvk.Kind)
if err != nil { if err != nil {
return nilValue, err return nilValue, err
} }
@ -175,25 +186,25 @@ func (o objects) Kind(kind, name string) (runtime.Object, error) {
} }
return out, nil return out, nil
} }
return nilValue, errors.NewNotFound(kind, name) return nilValue, errors.NewNotFound(gvk.Kind, name)
} }
index := o.last[kind] index := o.last[gvk.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(kind, name) return nilValue, errors.NewNotFound(gvk.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[kind] = index + 1 o.last[gvk.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 = kind status.Details.Kind = gvk.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

@ -72,10 +72,10 @@ func NewScheme() *Scheme {
cloner: NewCloner(), cloner: NewCloner(),
// TODO remove this hard coded list. As step one, hardcode it here so this pull doesn't become even bigger // TODO remove this hard coded list. As step one, hardcode it here so this pull doesn't become even bigger
InternalVersions: map[string]unversioned.GroupVersion{ InternalVersions: map[string]unversioned.GroupVersion{
"": unversioned.GroupVersion{}, "": {},
"componentconfig": unversioned.GroupVersion{Group: "componentconfig"}, "componentconfig": {Group: "componentconfig"},
"extensions": unversioned.GroupVersion{Group: "extensions"}, "extensions": {Group: "extensions"},
"metrics": unversioned.GroupVersion{Group: "metrics"}, "metrics": {Group: "metrics"},
}, },
MetaFactory: DefaultMetaFactory, MetaFactory: DefaultMetaFactory,
} }

View File

@ -84,7 +84,8 @@ var validVersionGV = unversioned.GroupVersion{Group: "apitest", Version: validVe
func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) { func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName(internalGV.Version, "Type", &internalType{}) scheme.AddInternalGroupVersion(internalGV)
scheme.AddKnownTypeWithName(internalGV.String(), "Type", &internalType{})
scheme.AddKnownTypeWithName(unlikelyGV.String(), "Type", &externalType{}) scheme.AddKnownTypeWithName(unlikelyGV.String(), "Type", &externalType{})
//This tests that kubectl will not confuse the external scheme with the internal scheme, even when they accidentally have versions of the same name. //This tests that kubectl will not confuse the external scheme with the internal scheme, even when they accidentally have versions of the same name.
scheme.AddKnownTypeWithName(validVersionGV.String(), "Type", &ExternalType2{}) scheme.AddKnownTypeWithName(validVersionGV.String(), "Type", &ExternalType2{})