Skip to content

Commit

Permalink
Merge pull request kubernetes#22853 from deads2k/parse-version
Browse files Browse the repository at this point in the history
allow resource.version.group in kubectl
  • Loading branch information
bgrant0607 authored and eparis committed Mar 11, 2016
1 parent 4aad581 commit 7d226b4
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 14 deletions.
2 changes: 1 addition & 1 deletion hack/test-cmd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ __EOF__
# Command: autoscale rc "frontend"
kubectl autoscale -f hack/testdata/frontend-controller.yaml --save-config "${kube_flags[@]}" --max=2
# Post-Condition: hpa "frontend" has configuration annotation
[[ "$(kubectl get hpa.extensions frontend -o yaml "${kube_flags[@]}" | grep kubectl.kubernetes.io/last-applied-configuration)" ]]
[[ "$(kubectl get hpa.v1beta1.extensions frontend -o yaml "${kube_flags[@]}" | grep kubectl.kubernetes.io/last-applied-configuration)" ]]
# Ensure we can interact with HPA objects in lists through both the extensions/v1beta1 and autoscaling/v1 APIs
output_message=$(kubectl get hpa -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]}")
kube::test::if_has_string "${output_message}" 'extensions/v1beta1'
Expand Down
15 changes: 15 additions & 0 deletions pkg/api/unversioned/group_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ import (
"strings"
)

// ParseResourceArg takes the common style of string which may be either `resource.group.com` or `resource.version.group.com`
// and parses it out into both possibilities. This code takes no responsibility for knowing which representation was intended
// but with a knowledge of all GroupVersions, calling code can take a very good guess. If there are only two segments, then
// `*GroupVersionResource` is nil.
// `resource.group.com` -> `group=com, version=group, resource=resource` and `group=group.com, resource=resource`
func ParseResourceArg(arg string) (*GroupVersionResource, GroupResource) {
var gvr *GroupVersionResource
s := strings.SplitN(arg, ".", 3)
if len(s) == 3 {
gvr = &GroupVersionResource{Group: s[2], Version: s[1], Resource: s[0]}
}

return gvr, ParseGroupResource(arg)
}

// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying
// concepts during lookup stages without having partially valid types
//
Expand Down
13 changes: 10 additions & 3 deletions pkg/kubectl/cmd/explain.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,16 @@ func RunExplain(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st
}

// TODO: We should deduce the group for a resource by discovering the supported resources at server.
gvk, err := mapper.KindFor(unversioned.ParseGroupResource(inModel).WithVersion(""))
if err != nil {
return err
fullySpecifiedGVR, groupResource := unversioned.ParseResourceArg(inModel)
gvk := unversioned.GroupVersionKind{}
if fullySpecifiedGVR != nil {
gvk, _ = mapper.KindFor(*fullySpecifiedGVR)
}
if gvk.IsEmpty() {
gvk, err = mapper.KindFor(groupResource.WithVersion(""))
if err != nil {
return err
}
}

if len(apiVersionString) == 0 {
Expand Down
33 changes: 23 additions & 10 deletions pkg/kubectl/resource/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,20 +433,36 @@ func (b *Builder) SingleResourceType() *Builder {
return b
}

// mappingFor returns the RESTMapping for the Kind referenced by the resource.
// prefers a fully specified GroupVersionResource match. If we don't have one match on GroupResource
func (b *Builder) mappingFor(resourceArg string) (*meta.RESTMapping, error) {
fullySpecifiedGVR, groupResource := unversioned.ParseResourceArg(resourceArg)
gvk := unversioned.GroupVersionKind{}
if fullySpecifiedGVR != nil {
gvk, _ = b.mapper.KindFor(*fullySpecifiedGVR)
}
if gvk.IsEmpty() {
var err error
gvk, err = b.mapper.KindFor(groupResource.WithVersion(""))
if err != nil {
return nil, err
}
}

return b.mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
}

func (b *Builder) resourceMappings() ([]*meta.RESTMapping, error) {
if len(b.resources) > 1 && b.singleResourceType {
return nil, fmt.Errorf("you may only specify a single resource type")
}
mappings := []*meta.RESTMapping{}
for _, r := range b.resources {
gvk, err := b.mapper.KindFor(unversioned.ParseGroupResource(r).WithVersion(""))
if err != nil {
return nil, err
}
mapping, err := b.mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
mapping, err := b.mappingFor(r)
if err != nil {
return nil, err
}

mappings = append(mappings, mapping)
}
return mappings, nil
Expand All @@ -459,14 +475,11 @@ func (b *Builder) resourceTupleMappings() (map[string]*meta.RESTMapping, error)
if _, ok := mappings[r.Resource]; ok {
continue
}
gvk, err := b.mapper.KindFor(unversioned.ParseGroupResource(r.Resource).WithVersion(""))
if err != nil {
return nil, err
}
mapping, err := b.mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
mapping, err := b.mappingFor(r.Resource)
if err != nil {
return nil, err
}

mappings[mapping.Resource] = mapping
mappings[r.Resource] = mapping
canonical[mapping.Resource] = struct{}{}
Expand Down

0 comments on commit 7d226b4

Please sign in to comment.