Add Identifier method to GroupVersioner interface

This commit is contained in:
wojtekt 2019-09-11 13:46:41 +02:00
parent 248549ba79
commit 36300c8c9f
5 changed files with 67 additions and 0 deletions

View File

@ -19,13 +19,17 @@ package runtime
import ( import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"encoding/json"
"fmt" "fmt"
"io" "io"
"net/url" "net/url"
"reflect" "reflect"
"strconv"
"strings"
"k8s.io/apimachinery/pkg/conversion/queryparams" "k8s.io/apimachinery/pkg/conversion/queryparams"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/klog"
) )
// codec binds an encoder and decoder. // codec binds an encoder and decoder.
@ -238,6 +242,11 @@ var (
DisabledGroupVersioner GroupVersioner = disabledGroupVersioner{} DisabledGroupVersioner GroupVersioner = disabledGroupVersioner{}
) )
const (
internalGroupVersionerIdentifier = "internal"
disabledGroupVersionerIdentifier = "disabled"
)
type internalGroupVersioner struct{} type internalGroupVersioner struct{}
// KindForGroupVersionKinds returns an internal Kind if one is found, or converts the first provided kind to the internal version. // KindForGroupVersionKinds returns an internal Kind if one is found, or converts the first provided kind to the internal version.
@ -253,6 +262,11 @@ func (internalGroupVersioner) KindForGroupVersionKinds(kinds []schema.GroupVersi
return schema.GroupVersionKind{}, false return schema.GroupVersionKind{}, false
} }
// Identifier implements GroupVersioner interface.
func (internalGroupVersioner) Identifier() string {
return internalGroupVersionerIdentifier
}
type disabledGroupVersioner struct{} type disabledGroupVersioner struct{}
// KindForGroupVersionKinds returns false for any input. // KindForGroupVersionKinds returns false for any input.
@ -260,6 +274,11 @@ func (disabledGroupVersioner) KindForGroupVersionKinds(kinds []schema.GroupVersi
return schema.GroupVersionKind{}, false return schema.GroupVersionKind{}, false
} }
// Identifier implements GroupVersioner interface.
func (disabledGroupVersioner) Identifier() string {
return disabledGroupVersionerIdentifier
}
// Assert that schema.GroupVersion and GroupVersions implement GroupVersioner // Assert that schema.GroupVersion and GroupVersions implement GroupVersioner
var _ GroupVersioner = schema.GroupVersion{} var _ GroupVersioner = schema.GroupVersion{}
var _ GroupVersioner = schema.GroupVersions{} var _ GroupVersioner = schema.GroupVersions{}
@ -315,3 +334,22 @@ func (v multiGroupVersioner) KindForGroupVersionKinds(kinds []schema.GroupVersio
} }
return schema.GroupVersionKind{}, false return schema.GroupVersionKind{}, false
} }
// Identifier implements GroupVersioner interface.
func (v multiGroupVersioner) Identifier() string {
groupKinds := make([]string, 0, len(v.acceptedGroupKinds))
for _, gk := range v.acceptedGroupKinds {
groupKinds = append(groupKinds, gk.String())
}
result := map[string]string{
"name": "multi",
"target": v.target.String(),
"accepted": strings.Join(groupKinds, ","),
"coerce": strconv.FormatBool(v.coerce),
}
identifier, err := json.Marshal(result)
if err != nil {
klog.Fatalf("Failed marshaling Identifier for %#v: %v", v, err)
}
return string(identifier)
}

View File

@ -39,6 +39,7 @@ func TestCoercingMultiGroupVersioner(t *testing.T) {
preferredKinds []schema.GroupKind preferredKinds []schema.GroupKind
kinds []schema.GroupVersionKind kinds []schema.GroupVersionKind
expectKind schema.GroupVersionKind expectKind schema.GroupVersionKind
expectedId string
}{ }{
{ {
name: "matched preferred group/kind", name: "matched preferred group/kind",
@ -46,6 +47,7 @@ func TestCoercingMultiGroupVersioner(t *testing.T) {
preferredKinds: []schema.GroupKind{gk("mygroup", "Foo"), gk("anothergroup", "Bar")}, preferredKinds: []schema.GroupKind{gk("mygroup", "Foo"), gk("anothergroup", "Bar")},
kinds: []schema.GroupVersionKind{gvk("yetanother", "v1", "Baz"), gvk("anothergroup", "v1", "Bar")}, kinds: []schema.GroupVersionKind{gvk("yetanother", "v1", "Baz"), gvk("anothergroup", "v1", "Bar")},
expectKind: gvk("mygroup", "__internal", "Bar"), expectKind: gvk("mygroup", "__internal", "Bar"),
expectedId: "{\"accepted\":\"Foo.mygroup,Bar.anothergroup\",\"coerce\":\"true\",\"name\":\"multi\",\"target\":\"mygroup/__internal\"}",
}, },
{ {
name: "matched preferred group", name: "matched preferred group",
@ -53,6 +55,7 @@ func TestCoercingMultiGroupVersioner(t *testing.T) {
preferredKinds: []schema.GroupKind{gk("mygroup", ""), gk("anothergroup", "")}, preferredKinds: []schema.GroupKind{gk("mygroup", ""), gk("anothergroup", "")},
kinds: []schema.GroupVersionKind{gvk("yetanother", "v1", "Baz"), gvk("anothergroup", "v1", "Bar")}, kinds: []schema.GroupVersionKind{gvk("yetanother", "v1", "Baz"), gvk("anothergroup", "v1", "Bar")},
expectKind: gvk("mygroup", "__internal", "Bar"), expectKind: gvk("mygroup", "__internal", "Bar"),
expectedId: "{\"accepted\":\".mygroup,.anothergroup\",\"coerce\":\"true\",\"name\":\"multi\",\"target\":\"mygroup/__internal\"}",
}, },
{ {
name: "no preferred group/kind match, uses first kind in list", name: "no preferred group/kind match, uses first kind in list",
@ -60,6 +63,7 @@ func TestCoercingMultiGroupVersioner(t *testing.T) {
preferredKinds: []schema.GroupKind{gk("mygroup", ""), gk("anothergroup", "")}, preferredKinds: []schema.GroupKind{gk("mygroup", ""), gk("anothergroup", "")},
kinds: []schema.GroupVersionKind{gvk("yetanother", "v1", "Baz"), gvk("yetanother", "v1", "Bar")}, kinds: []schema.GroupVersionKind{gvk("yetanother", "v1", "Baz"), gvk("yetanother", "v1", "Bar")},
expectKind: gvk("mygroup", "__internal", "Baz"), expectKind: gvk("mygroup", "__internal", "Baz"),
expectedId: "{\"accepted\":\".mygroup,.anothergroup\",\"coerce\":\"true\",\"name\":\"multi\",\"target\":\"mygroup/__internal\"}",
}, },
} }
@ -73,6 +77,9 @@ func TestCoercingMultiGroupVersioner(t *testing.T) {
if kind != tc.expectKind { if kind != tc.expectKind {
t.Errorf("expected %#v, got %#v", tc.expectKind, kind) t.Errorf("expected %#v, got %#v", tc.expectKind, kind)
} }
if e, a := tc.expectedId, v.Identifier(); e != a {
t.Errorf("unexpected identifier: %s, expected: %s", a, e)
}
}) })
} }
} }

View File

@ -37,6 +37,10 @@ type GroupVersioner interface {
// Scheme.New(target) and then perform a conversion between the current Go type and the destination Go type. // Scheme.New(target) and then perform a conversion between the current Go type and the destination Go type.
// Sophisticated implementations may use additional information about the input kinds to pick a destination kind. // Sophisticated implementations may use additional information about the input kinds to pick a destination kind.
KindForGroupVersionKinds(kinds []schema.GroupVersionKind) (target schema.GroupVersionKind, ok bool) KindForGroupVersionKinds(kinds []schema.GroupVersionKind) (target schema.GroupVersionKind, ok bool)
// Identifier returns string representation of the object.
// Identifiers of two different encoders should be equal only if for every input
// kinds they return the same result.
Identifier() string
} }
// Identifier represents an identifier. // Identifier represents an identifier.

View File

@ -191,6 +191,11 @@ func (gv GroupVersion) String() string {
return gv.Version return gv.Version
} }
// Identifier implements runtime.GroupVersioner interface.
func (gv GroupVersion) Identifier() string {
return gv.String()
}
// 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. It prefers a match to group and version over just group. // if none of the options match the group. It prefers a match to group and version over just group.
// TODO: Move GroupVersion to a package under pkg/runtime, since it's used by scheme. // TODO: Move GroupVersion to a package under pkg/runtime, since it's used by scheme.
@ -246,6 +251,15 @@ func (gv GroupVersion) WithResource(resource string) GroupVersionResource {
// in fewer places. // in fewer places.
type GroupVersions []GroupVersion type GroupVersions []GroupVersion
// Identifier implements runtime.GroupVersioner interface.
func (gv GroupVersions) Identifier() string {
groupVersions := make([]string, 0, len(gv))
for i := range gv {
groupVersions = append(groupVersions, gv[i].String())
}
return fmt.Sprintf("[%s]", strings.Join(groupVersions, ","))
}
// 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) (GroupVersionKind, bool) { func (gvs GroupVersions) KindForGroupVersionKinds(kinds []GroupVersionKind) (GroupVersionKind, bool) {

View File

@ -610,6 +610,10 @@ func (m testGroupVersioner) KindForGroupVersionKinds(kinds []schema.GroupVersion
return m.target, m.ok return m.target, m.ok
} }
func (m testGroupVersioner) Identifier() string {
return "testGroupVersioner"
}
func TestConvertToVersion(t *testing.T) { func TestConvertToVersion(t *testing.T) {
testCases := []struct { testCases := []struct {
scheme *runtime.Scheme scheme *runtime.Scheme