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")}
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 {
// programmer error
return nil, err
gvString = "v1"
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 {
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 {
// programmer error
return nil, err

View File

@ -38,7 +38,7 @@ import (
type ObjectRetriever interface {
// 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.
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(runtime.Object) error
}
@ -59,23 +59,29 @@ type ObjectScheme interface {
func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {
return func(action Action) (bool, runtime.Object, error) {
_, kind, err := mapper.VersionAndKindForResource(action.GetResource())
gvString, kind, err := mapper.VersionAndKindForResource(action.GetResource())
if err != nil {
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?
switch castAction := action.(type) {
case ListAction:
resource, err := o.Kind(kind+"List", "")
gvk.Kind += "List"
resource, err := o.Kind(gvk, "")
return true, resource, err
case GetAction:
resource, err := o.Kind(kind, castAction.GetName())
resource, err := o.Kind(gvk, castAction.GetName())
return true, resource, err
case DeleteAction:
resource, err := o.Kind(kind, castAction.GetName())
resource, err := o.Kind(gvk, castAction.GetName())
return true, resource, err
case CreateAction:
@ -83,7 +89,7 @@ func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {
if err != nil {
return true, nil, err
}
resource, err := o.Kind(kind, meta.Name)
resource, err := o.Kind(gvk, meta.Name)
return true, resource, err
case UpdateAction:
@ -91,7 +97,7 @@ func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {
if err != nil {
return true, nil, err
}
resource, err := o.Kind(kind, meta.Name)
resource, err := o.Kind(gvk, meta.Name)
return true, resource, err
default:
@ -151,19 +157,24 @@ func NewObjects(scheme ObjectScheme, decoder runtime.ObjectDecoder) ObjectRetrie
}
}
func (o objects) Kind(kind, name string) (runtime.Object, error) {
empty, _ := o.scheme.New("", kind)
func (o objects) Kind(gvk unversioned.GroupVersionKind, name string) (runtime.Object, error) {
// 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)
arr, ok := o.types[kind]
arr, ok := o.types[gvk.Kind]
if !ok {
if strings.HasSuffix(kind, "List") {
itemKind := kind[:len(kind)-4]
if strings.HasSuffix(gvk.Kind, "List") {
itemKind := gvk.Kind[:len(gvk.Kind)-4]
arr, ok := o.types[itemKind]
if !ok {
return empty, nil
}
out, err := o.scheme.New("", kind)
out, err := o.scheme.New(gvk.GroupVersion().String(), gvk.Kind)
if err != nil {
return nilValue, err
}
@ -175,25 +186,25 @@ func (o objects) Kind(kind, name string) (runtime.Object, error) {
}
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) {
index = len(arr) - 1
}
if index < 0 {
return nilValue, errors.NewNotFound(kind, name)
return nilValue, errors.NewNotFound(gvk.Kind, name)
}
out, err := o.scheme.Copy(arr[index])
if err != nil {
return nilValue, err
}
o.last[kind] = index + 1
o.last[gvk.Kind] = index + 1
if status, ok := out.(*unversioned.Status); ok {
if status.Details != nil {
status.Details.Kind = kind
status.Details.Kind = gvk.Kind
}
if status.Status != unversioned.StatusSuccess {
return nilValue, &errors.StatusError{ErrStatus: *status}

View File

@ -72,10 +72,10 @@ func NewScheme() *Scheme {
cloner: NewCloner(),
// 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{
"": unversioned.GroupVersion{},
"componentconfig": unversioned.GroupVersion{Group: "componentconfig"},
"extensions": unversioned.GroupVersion{Group: "extensions"},
"metrics": unversioned.GroupVersion{Group: "metrics"},
"": {},
"componentconfig": {Group: "componentconfig"},
"extensions": {Group: "extensions"},
"metrics": {Group: "metrics"},
},
MetaFactory: DefaultMetaFactory,
}

View File

@ -84,7 +84,8 @@ var validVersionGV = unversioned.GroupVersion{Group: "apitest", Version: validVe
func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName(internalGV.Version, "Type", &internalType{})
scheme.AddInternalGroupVersion(internalGV)
scheme.AddKnownTypeWithName(internalGV.String(), "Type", &internalType{})
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.
scheme.AddKnownTypeWithName(validVersionGV.String(), "Type", &ExternalType2{})