Match GroupVersionKind against specific version

This commit is contained in:
Maciej Szulik 2016-10-04 14:00:47 +02:00
parent 1dc8277507
commit 69f751a2a4
3 changed files with 71 additions and 4 deletions

View File

@ -268,17 +268,37 @@ type GroupVersions []GroupVersion
// KindForGroupVersionKinds identifies the preferred GroupVersionKind out of a list. It returns ok false // KindForGroupVersionKinds identifies the preferred GroupVersionKind out of a list. It returns ok false
// if none of the options match the group. // if none of the options match the group.
func (gvs GroupVersions) KindForGroupVersionKinds(kinds []GroupVersionKind) (target GroupVersionKind, ok bool) { func (gvs GroupVersions) KindForGroupVersionKinds(kinds []GroupVersionKind) (GroupVersionKind, bool) {
var targets []GroupVersionKind
for _, gv := range gvs { for _, gv := range gvs {
target, ok := gv.KindForGroupVersionKinds(kinds) target, ok := gv.KindForGroupVersionKinds(kinds)
if !ok { if !ok {
continue continue
} }
return target, true targets = append(targets, target)
}
if len(targets) == 1 {
return targets[0], true
}
if len(targets) > 1 {
return bestMatch(kinds, targets), true
} }
return GroupVersionKind{}, false return GroupVersionKind{}, false
} }
// bestMatch tries to pick best matching GroupVersionKind and falls back to the first
// found if no exact match exists.
func bestMatch(kinds []GroupVersionKind, targets []GroupVersionKind) GroupVersionKind {
for _, gvk := range targets {
for _, k := range kinds {
if k == gvk {
return k
}
}
}
return targets[0]
}
// ToAPIVersionAndKind is a convenience method for satisfying runtime.Object on types that // ToAPIVersionAndKind is a convenience method for satisfying runtime.Object on types that
// do not use TypeMeta. // do not use TypeMeta.
func (gvk *GroupVersionKind) ToAPIVersionAndKind() (string, string) { func (gvk *GroupVersionKind) ToAPIVersionAndKind() (string, string) {

View File

@ -147,3 +147,47 @@ func TestGroupVersionMarshalJSON(t *testing.T) {
} }
} }
} }
func TestKindForGroupVersionKinds(t *testing.T) {
gvks := GroupVersions{
GroupVersion{Group: "batch", Version: "v1"},
GroupVersion{Group: "batch", Version: "v2alpha1"},
GroupVersion{Group: "policy", Version: "v1alpha1"},
}
cases := []struct {
input []GroupVersionKind
target GroupVersionKind
ok bool
}{
{
input: []GroupVersionKind{{Group: "batch", Version: "v2alpha1", Kind: "ScheduledJob"}},
target: GroupVersionKind{Group: "batch", Version: "v2alpha1", Kind: "ScheduledJob"},
ok: true,
},
{
input: []GroupVersionKind{{Group: "batch", Version: "v3alpha1", Kind: "CronJob"}},
target: GroupVersionKind{Group: "batch", Version: "v1", Kind: "CronJob"},
ok: true,
},
{
input: []GroupVersionKind{{Group: "policy", Version: "v1alpha1", Kind: "PodDisruptionBudget"}},
target: GroupVersionKind{Group: "policy", Version: "v1alpha1", Kind: "PodDisruptionBudget"},
ok: true,
},
{
input: []GroupVersionKind{{Group: "apps", Version: "v1alpha1", Kind: "PetSet"}},
target: GroupVersionKind{},
ok: false,
},
}
for i, c := range cases {
target, ok := gvks.KindForGroupVersionKinds(c.input)
if c.target != target {
t.Errorf("%d: unexpected target: %v, expected %v", i, target, c.target)
}
if c.ok != ok {
t.Errorf("%d: unexpected ok: %v, expected %v", i, ok, c.ok)
}
}
}

View File

@ -602,12 +602,15 @@ func TestConvertToVersion(t *testing.T) {
gv: unversioned.GroupVersion{Version: "__internal"}, gv: unversioned.GroupVersion{Version: "__internal"},
out: &TestType1{A: "test"}, out: &TestType1{A: "test"},
}, },
// prefers the first group version in the list // prefers the best match
{ {
scheme: GetTestScheme(), scheme: GetTestScheme(),
in: &ExternalTestType1{A: "test"}, in: &ExternalTestType1{A: "test"},
gv: unversioned.GroupVersions{{Version: "__internal"}, {Version: "v1"}}, gv: unversioned.GroupVersions{{Version: "__internal"}, {Version: "v1"}},
out: &TestType1{A: "test"}, out: &ExternalTestType1{
MyWeirdCustomEmbeddedVersionKindField: MyWeirdCustomEmbeddedVersionKindField{APIVersion: "v1", ObjectKind: "TestType1"},
A: "test",
},
}, },
// unversioned type returned as-is // unversioned type returned as-is
{ {