Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefer fetched version when determining HPA group version kind #22840

Merged
merged 1 commit into from Mar 11, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions hack/test-cmd.sh
Expand Up @@ -729,6 +729,13 @@ __EOF__
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)" ]]
# 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'
output_message=$(kubectl get hpa.extensions -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]}")
kube::test::if_has_string "${output_message}" 'extensions/v1beta1'
output_message=$(kubectl get hpa.autoscaling -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]}")
kube::test::if_has_string "${output_message}" 'autoscaling/v1'
# Clean up
# Note that we should delete hpa first, otherwise it may fight with the rc reaper.
kubectl delete hpa frontend "${kube_flags[@]}"
Expand Down
2 changes: 1 addition & 1 deletion pkg/kubectl/cmd/autoscale.go
Expand Up @@ -136,7 +136,7 @@ func RunAutoscale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
Decoder: f.Decoder(true),
}
hpa, err := resourceMapper.InfoForObject(object)
hpa, err := resourceMapper.InfoForObject(object, nil)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/kubectl/cmd/create.go
Expand Up @@ -236,7 +236,7 @@ func RunCreateSubcommand(f *cmdutil.Factory, cmd *cobra.Command, out io.Writer,
RESTMapper: mapper,
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
}
info, err := resourceMapper.InfoForObject(obj)
info, err := resourceMapper.InfoForObject(obj, nil)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/kubectl/cmd/expose.go
Expand Up @@ -212,7 +212,7 @@ func RunExpose(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
Decoder: f.Decoder(true),
}
info, err = resourceMapper.InfoForObject(object)
info, err = resourceMapper.InfoForObject(object, nil)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/kubectl/cmd/run.go
Expand Up @@ -441,7 +441,7 @@ func createGeneratedObject(f *cmdutil.Factory, cmd *cobra.Command, generator kub
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
Decoder: f.Decoder(true),
}
info, err := resourceMapper.InfoForObject(obj)
info, err := resourceMapper.InfoForObject(obj, nil)
if err != nil {
return nil, "", nil, nil, err
}
Expand Down
47 changes: 45 additions & 2 deletions pkg/kubectl/resource/mapper.go
Expand Up @@ -21,6 +21,7 @@ import (
"reflect"

"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
)

Expand Down Expand Up @@ -85,11 +86,17 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) {
// InfoForObject creates an Info object for the given Object. An error is returned
// if the object cannot be introspected. Name and namespace will be set into Info
// if the mapping's MetadataAccessor can retrieve them.
func (m *Mapper) InfoForObject(obj runtime.Object) (*Info, error) {
groupVersionKind, err := m.ObjectKind(obj)
func (m *Mapper) InfoForObject(obj runtime.Object, preferredGVKs []unversioned.GroupVersionKind) (*Info, error) {
groupVersionKinds, err := m.ObjectKinds(obj)
if err != nil {
return nil, fmt.Errorf("unable to get type info from the object %q: %v", reflect.TypeOf(obj), err)
}

groupVersionKind := groupVersionKinds[0]
if len(groupVersionKinds) > 1 && len(preferredGVKs) > 0 {
groupVersionKind = preferredObjectKind(groupVersionKinds, preferredGVKs)
}

mapping, err := m.RESTMapping(groupVersionKind.GroupKind(), groupVersionKind.Version)
if err != nil {
return nil, fmt.Errorf("unable to recognize %v: %v", groupVersionKind, err)
Expand All @@ -111,3 +118,39 @@ func (m *Mapper) InfoForObject(obj runtime.Object) (*Info, error) {
ResourceVersion: resourceVersion,
}, nil
}

// preferredObjectKind picks the possibility that most closely matches the priority list in this order:
// GroupVersionKind matches (exact match)
// GroupKind matches
// Group matches
func preferredObjectKind(possibilities []unversioned.GroupVersionKind, preferences []unversioned.GroupVersionKind) unversioned.GroupVersionKind {
// Exact match
for _, priority := range preferences {
for _, possibility := range possibilities {
if possibility == priority {
return possibility
}
}
}

// GroupKind match
for _, priority := range preferences {
for _, possibility := range possibilities {
if possibility.GroupKind() == priority.GroupKind() {
return possibility
}
}
}

// Group match
for _, priority := range preferences {
for _, possibility := range possibilities {
if possibility.Group == priority.Group {
return possibility
}
}
}

// Just pick the first
return possibilities[0]
}
10 changes: 9 additions & 1 deletion pkg/kubectl/resource/visitor.go
Expand Up @@ -26,6 +26,7 @@ import (
"path/filepath"

"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/runtime"
utilerrors "k8s.io/kubernetes/pkg/util/errors"
Expand Down Expand Up @@ -337,8 +338,15 @@ func (v FlattenListVisitor) Visit(fn VisitorFunc) error {
}{v.Mapper, v.Mapper.Decoder}); len(errs) > 0 {
return utilerrors.NewAggregate(errs)
}

// If we have a GroupVersionKind on the list, prioritize that when asking for info on the objects contained in the list
var preferredGVKs []unversioned.GroupVersionKind
if info.Mapping != nil && !info.Mapping.GroupVersionKind.IsEmpty() {
preferredGVKs = append(preferredGVKs, info.Mapping.GroupVersionKind)
}

for i := range items {
item, err := v.InfoForObject(items[i])
item, err := v.InfoForObject(items[i], preferredGVKs)
if err != nil {
return err
}
Expand Down