mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 15:25:57 +00:00
internal versions
This commit is contained in:
parent
6231404682
commit
68b0572974
@ -41,7 +41,7 @@ func BenchmarkPodConversion(b *testing.B) {
|
||||
if err != nil {
|
||||
b.Fatalf("Conversion error: %v", err)
|
||||
}
|
||||
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersion)
|
||||
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersions[testapi.Default.Group].String())
|
||||
if err != nil {
|
||||
b.Fatalf("Conversion error: %v", err)
|
||||
}
|
||||
@ -69,7 +69,7 @@ func BenchmarkNodeConversion(b *testing.B) {
|
||||
if err != nil {
|
||||
b.Fatalf("Conversion error: %v", err)
|
||||
}
|
||||
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersion)
|
||||
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersions[testapi.Default.Group].String())
|
||||
if err != nil {
|
||||
b.Fatalf("Conversion error: %v", err)
|
||||
}
|
||||
@ -97,7 +97,7 @@ func BenchmarkReplicationControllerConversion(b *testing.B) {
|
||||
if err != nil {
|
||||
b.Fatalf("Conversion error: %v", err)
|
||||
}
|
||||
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersion)
|
||||
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersions[testapi.Default.Group].String())
|
||||
if err != nil {
|
||||
b.Fatalf("Conversion error: %v", err)
|
||||
}
|
||||
|
@ -49,11 +49,15 @@ type GroupVersion struct {
|
||||
Version string
|
||||
}
|
||||
|
||||
func (gv GroupVersion) IsEmpty() bool {
|
||||
return len(gv.Group) == 0 && len(gv.Version) == 0
|
||||
}
|
||||
|
||||
// String puts "group" and "version" into a single "group/version" string. For the legacy v1
|
||||
// it returns "v1".
|
||||
func (gv GroupVersion) String() string {
|
||||
// special case the internal apiVersion for kube
|
||||
if len(gv.Group) == 0 && len(gv.Version) == 0 {
|
||||
if gv.IsEmpty() {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,8 @@ func init() {
|
||||
}
|
||||
|
||||
func addKnownTypes() {
|
||||
api.Scheme.AddKnownTypes("",
|
||||
// TODO this will get cleaned up with the scheme types are fixed
|
||||
api.Scheme.AddKnownTypes("componentconfig/",
|
||||
&KubeProxyConfiguration{},
|
||||
)
|
||||
}
|
||||
|
@ -27,7 +27,8 @@ func init() {
|
||||
|
||||
// Adds the list of known types to api.Scheme.
|
||||
func addKnownTypes() {
|
||||
api.Scheme.AddKnownTypes("",
|
||||
// TODO this gets cleaned up when the types are fixed
|
||||
api.Scheme.AddKnownTypes("extensions/",
|
||||
&ClusterAutoscaler{},
|
||||
&ClusterAutoscalerList{},
|
||||
&Deployment{},
|
||||
|
@ -27,7 +27,8 @@ func init() {
|
||||
|
||||
// Adds the list of known types to api.Scheme.
|
||||
func addKnownTypes() {
|
||||
api.Scheme.AddKnownTypes("",
|
||||
// TODO this will get cleaned up with the scheme types are fixed
|
||||
api.Scheme.AddKnownTypes("metrics/",
|
||||
&RawNode{},
|
||||
&RawPod{},
|
||||
)
|
||||
|
@ -375,11 +375,14 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
||||
// test/integration/auth_test.go is currently the most comprehensive status code test
|
||||
|
||||
reqScope := RequestScope{
|
||||
ContextFunc: ctxFn,
|
||||
Creater: a.group.Creater,
|
||||
Convertor: a.group.Convertor,
|
||||
Codec: mapping.Codec,
|
||||
APIVersion: a.group.GroupVersion.String(),
|
||||
ContextFunc: ctxFn,
|
||||
Creater: a.group.Creater,
|
||||
Convertor: a.group.Convertor,
|
||||
Codec: mapping.Codec,
|
||||
APIVersion: a.group.GroupVersion.String(),
|
||||
// TODO, this internal version needs to plumbed through from the caller
|
||||
// this works in all the cases we have now
|
||||
InternalVersion: unversioned.GroupVersion{Group: a.group.GroupVersion.Group},
|
||||
ServerAPIVersion: serverGroupVersion.String(),
|
||||
Resource: resource,
|
||||
Subresource: subresource,
|
||||
|
@ -58,6 +58,7 @@ func convert(obj runtime.Object) (runtime.Object, error) {
|
||||
|
||||
// This creates fake API versions, similar to api/latest.go.
|
||||
var testAPIGroup = "test.group"
|
||||
var testInternalGroupVersion = unversioned.GroupVersion{Group: testAPIGroup, Version: ""}
|
||||
var testGroupVersion = unversioned.GroupVersion{Group: testAPIGroup, Version: "version"}
|
||||
var newGroupVersion = unversioned.GroupVersion{Group: testAPIGroup, Version: "version2"}
|
||||
var prefix = "apis"
|
||||
@ -136,8 +137,9 @@ func init() {
|
||||
|
||||
// "internal" version
|
||||
api.Scheme.AddKnownTypes(
|
||||
"", &apiservertesting.Simple{}, &apiservertesting.SimpleList{}, &unversioned.Status{},
|
||||
testInternalGroupVersion.String(), &apiservertesting.Simple{}, &apiservertesting.SimpleList{}, &unversioned.Status{},
|
||||
&unversioned.ListOptions{}, &apiservertesting.SimpleGetOptions{}, &apiservertesting.SimpleRoot{})
|
||||
api.Scheme.AddInternalGroupVersion(testInternalGroupVersion)
|
||||
addGrouplessTypes()
|
||||
addTestTypes()
|
||||
addNewTestTypes()
|
||||
@ -1630,7 +1632,7 @@ func TestConnectWithOptions(t *testing.T) {
|
||||
}
|
||||
opts, ok := connectStorage.receivedConnectOptions.(*apiservertesting.SimpleGetOptions)
|
||||
if !ok {
|
||||
t.Errorf("Unexpected options type: %#v", connectStorage.receivedConnectOptions)
|
||||
t.Fatalf("Unexpected options type: %#v", connectStorage.receivedConnectOptions)
|
||||
}
|
||||
if opts.Param1 != "value1" && opts.Param2 != "value2" {
|
||||
t.Errorf("Unexpected options value: %#v", opts)
|
||||
@ -1677,7 +1679,7 @@ func TestConnectWithOptionsAndPath(t *testing.T) {
|
||||
}
|
||||
opts, ok := connectStorage.receivedConnectOptions.(*apiservertesting.SimpleGetOptions)
|
||||
if !ok {
|
||||
t.Errorf("Unexpected options type: %#v", connectStorage.receivedConnectOptions)
|
||||
t.Fatalf("Unexpected options type: %#v", connectStorage.receivedConnectOptions)
|
||||
}
|
||||
if opts.Param1 != "value1" && opts.Param2 != "value2" {
|
||||
t.Errorf("Unexpected options value: %#v", opts)
|
||||
|
@ -73,10 +73,11 @@ type RequestScope struct {
|
||||
Creater runtime.ObjectCreater
|
||||
Convertor runtime.ObjectConvertor
|
||||
|
||||
Resource string
|
||||
Subresource string
|
||||
Kind string
|
||||
APIVersion string
|
||||
Resource string
|
||||
Subresource string
|
||||
Kind string
|
||||
APIVersion string
|
||||
InternalVersion unversioned.GroupVersion
|
||||
|
||||
// The version of apiserver resources to use
|
||||
ServerAPIVersion string
|
||||
@ -156,7 +157,7 @@ func getRequestOptions(req *restful.Request, scope RequestScope, kind string, su
|
||||
if err := scope.Codec.DecodeParametersInto(query, versioned); err != nil {
|
||||
return nil, errors.NewBadRequest(err.Error())
|
||||
}
|
||||
out, err := scope.Convertor.ConvertToVersion(versioned, "")
|
||||
out, err := scope.Convertor.ConvertToVersion(versioned, scope.InternalVersion.String())
|
||||
if err != nil {
|
||||
// programmer error
|
||||
return nil, err
|
||||
|
@ -26,18 +26,29 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
func (s *Scheme) DecodeToVersionedObject(data []byte) (obj interface{}, version, kind string, err error) {
|
||||
version, kind, err = s.DataVersionAndKind(data)
|
||||
func (s *Scheme) DecodeToVersionedObject(data []byte) (interface{}, string, string, error) {
|
||||
version, kind, err := s.DataVersionAndKind(data)
|
||||
if err != nil {
|
||||
return
|
||||
return nil, "", "", err
|
||||
}
|
||||
if version == "" && s.InternalVersion != "" {
|
||||
|
||||
gv, err := unversioned.ParseGroupVersion(version)
|
||||
if err != nil {
|
||||
return nil, "", "", err
|
||||
}
|
||||
|
||||
internalGV, exists := s.InternalVersions[gv.Group]
|
||||
if !exists {
|
||||
return nil, "", "", fmt.Errorf("no internalVersion specified for %v", gv)
|
||||
}
|
||||
|
||||
if len(gv.Version) == 0 && len(internalGV.Version) != 0 {
|
||||
return nil, "", "", fmt.Errorf("version not set in '%s'", string(data))
|
||||
}
|
||||
if kind == "" {
|
||||
return nil, "", "", fmt.Errorf("kind not set in '%s'", string(data))
|
||||
}
|
||||
obj, err = s.NewObject(version, kind)
|
||||
obj, err := s.NewObject(version, kind)
|
||||
if err != nil {
|
||||
return nil, "", "", err
|
||||
}
|
||||
@ -45,7 +56,7 @@ func (s *Scheme) DecodeToVersionedObject(data []byte) (obj interface{}, version,
|
||||
if err := codec.NewDecoderBytes(data, new(codec.JsonHandle)).Decode(obj); err != nil {
|
||||
return nil, "", "", err
|
||||
}
|
||||
return
|
||||
return obj, version, kind, nil
|
||||
}
|
||||
|
||||
// Decode converts a JSON string back into a pointer to an api object.
|
||||
@ -54,8 +65,7 @@ func (s *Scheme) DecodeToVersionedObject(data []byte) (obj interface{}, version,
|
||||
// s.InternalVersion type before being returned. Decode will not decode
|
||||
// objects without version set unless InternalVersion is also "".
|
||||
func (s *Scheme) Decode(data []byte) (interface{}, error) {
|
||||
// TODO this is cleaned up when internal types are fixed
|
||||
return s.DecodeToVersion(data, unversioned.ParseGroupVersionOrDie(s.InternalVersion))
|
||||
return s.DecodeToVersion(data, unversioned.GroupVersion{})
|
||||
}
|
||||
|
||||
// DecodeToVersion converts a JSON string back into a pointer to an api object.
|
||||
@ -63,6 +73,8 @@ func (s *Scheme) Decode(data []byte) (interface{}, error) {
|
||||
// technique. The object will be converted, if necessary, into the versioned
|
||||
// type before being returned. Decode will not decode objects without version
|
||||
// set unless version is also "".
|
||||
// a GroupVersion with .IsEmpty() == true is means "use the internal version for
|
||||
// the object's group"
|
||||
func (s *Scheme) DecodeToVersion(data []byte, gv unversioned.GroupVersion) (interface{}, error) {
|
||||
obj, sourceVersion, kind, err := s.DecodeToVersionedObject(data)
|
||||
if err != nil {
|
||||
@ -73,8 +85,23 @@ func (s *Scheme) DecodeToVersion(data []byte, gv unversioned.GroupVersion) (inte
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sourceGV, err := unversioned.ParseGroupVersion(sourceVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if the gv is empty, then we want the internal version, but the internal version varies by
|
||||
// group. We can lookup the group now because we have knowledge of the group
|
||||
if gv.IsEmpty() {
|
||||
exists := false
|
||||
gv, exists = s.InternalVersions[sourceGV.Group]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf("no internalVersion specified for %v", gv)
|
||||
}
|
||||
}
|
||||
|
||||
// Convert if needed.
|
||||
if gv.String() != sourceVersion {
|
||||
if gv != sourceGV {
|
||||
objOut, err := s.NewObject(gv.String(), kind)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -118,7 +145,7 @@ func (s *Scheme) DecodeIntoWithSpecifiedVersionKind(data []byte, obj interface{}
|
||||
if dataKind == "" {
|
||||
dataKind = gvk.Kind
|
||||
}
|
||||
if (len(gvk.GroupVersion().Group) > 0 || len(gvk.GroupVersion().Version) > 0) && (dataVersion != gvk.GroupVersion().String()) {
|
||||
if (len(gvk.Group) > 0 || len(gvk.Version) > 0) && (dataVersion != gvk.GroupVersion().String()) {
|
||||
return errors.New(fmt.Sprintf("The apiVersion in the data (%s) does not match the specified apiVersion(%v)", dataVersion, gvk.GroupVersion()))
|
||||
}
|
||||
if len(gvk.Kind) > 0 && (dataKind != gvk.Kind) {
|
||||
|
@ -19,25 +19,27 @@ package conversion
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
type notRegisteredErr struct {
|
||||
kind string
|
||||
version string
|
||||
t reflect.Type
|
||||
gvk unversioned.GroupVersionKind
|
||||
t reflect.Type
|
||||
}
|
||||
|
||||
func (k *notRegisteredErr) Error() string {
|
||||
if k.t != nil {
|
||||
return fmt.Sprintf("no kind is registered for the type %v", k.t)
|
||||
}
|
||||
if len(k.kind) == 0 {
|
||||
return fmt.Sprintf("no version %q has been registered", k.version)
|
||||
if len(k.gvk.Kind) == 0 {
|
||||
return fmt.Sprintf("no version %q has been registered", k.gvk.GroupVersion())
|
||||
}
|
||||
if len(k.version) == 0 {
|
||||
return fmt.Sprintf("no kind %q is registered for the default version", k.kind)
|
||||
if len(k.gvk.Version) == 0 {
|
||||
return fmt.Sprintf("no kind %q is registered for the default version of group %q", k.gvk.Kind, k.gvk.Group)
|
||||
}
|
||||
return fmt.Sprintf("no kind %q is registered for version %q", k.kind, k.version)
|
||||
|
||||
return fmt.Sprintf("no kind %q is registered for version %q", k.gvk.Kind, k.gvk.GroupVersion())
|
||||
}
|
||||
|
||||
// IsNotRegisteredError returns true if the error indicates the provided
|
||||
|
@ -125,9 +125,13 @@ func TestMetaValues(t *testing.T) {
|
||||
Kind string `json:"kind,omitempty"`
|
||||
TestString string `json:"testString"`
|
||||
}
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "externalVersion"}
|
||||
|
||||
s := NewScheme()
|
||||
s.AddKnownTypeWithName("", "Simple", &InternalSimple{})
|
||||
s.AddKnownTypeWithName("externalVersion", "Simple", &ExternalSimple{})
|
||||
s.InternalVersions[internalGV.Group] = internalGV
|
||||
s.AddKnownTypeWithName(internalGV.String(), "Simple", &InternalSimple{})
|
||||
s.AddKnownTypeWithName(externalGV.String(), "Simple", &ExternalSimple{})
|
||||
|
||||
internalToExternalCalls := 0
|
||||
externalToInternalCalls := 0
|
||||
@ -136,10 +140,10 @@ func TestMetaValues(t *testing.T) {
|
||||
err := s.AddConversionFuncs(
|
||||
func(in *InternalSimple, out *ExternalSimple, scope Scope) error {
|
||||
t.Logf("internal -> external")
|
||||
if e, a := "", scope.Meta().SrcVersion; e != a {
|
||||
if e, a := internalGV.String(), scope.Meta().SrcVersion; e != a {
|
||||
t.Fatalf("Expected '%v', got '%v'", e, a)
|
||||
}
|
||||
if e, a := "externalVersion", scope.Meta().DestVersion; e != a {
|
||||
if e, a := externalGV.String(), scope.Meta().DestVersion; e != a {
|
||||
t.Fatalf("Expected '%v', got '%v'", e, a)
|
||||
}
|
||||
scope.Convert(&in.TestString, &out.TestString, 0)
|
||||
@ -148,10 +152,10 @@ func TestMetaValues(t *testing.T) {
|
||||
},
|
||||
func(in *ExternalSimple, out *InternalSimple, scope Scope) error {
|
||||
t.Logf("external -> internal")
|
||||
if e, a := "externalVersion", scope.Meta().SrcVersion; e != a {
|
||||
if e, a := externalGV.String(), scope.Meta().SrcVersion; e != a {
|
||||
t.Errorf("Expected '%v', got '%v'", e, a)
|
||||
}
|
||||
if e, a := "", scope.Meta().DestVersion; e != a {
|
||||
if e, a := internalGV.String(), scope.Meta().DestVersion; e != a {
|
||||
t.Fatalf("Expected '%v', got '%v'", e, a)
|
||||
}
|
||||
scope.Convert(&in.TestString, &out.TestString, 0)
|
||||
@ -169,7 +173,7 @@ func TestMetaValues(t *testing.T) {
|
||||
s.Log(t)
|
||||
|
||||
// Test Encode, Decode, and DecodeInto
|
||||
data, err := s.EncodeToVersion(simple, "externalVersion")
|
||||
data, err := s.EncodeToVersion(simple, externalGV.String())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@ -226,7 +230,6 @@ func TestMetaValuesUnregisteredConvert(t *testing.T) {
|
||||
TestString string `json:"testString"`
|
||||
}
|
||||
s := NewScheme()
|
||||
s.InternalVersion = ""
|
||||
// We deliberately don't register the types.
|
||||
|
||||
internalToExternalCalls := 0
|
||||
|
@ -19,6 +19,8 @@ package conversion
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
)
|
||||
|
||||
// Scheme defines an entire encoding and decoding scheme.
|
||||
@ -50,7 +52,9 @@ type Scheme struct {
|
||||
|
||||
// InternalVersion is the default internal version. It is recommended that
|
||||
// you use "" for the internal version.
|
||||
InternalVersion string
|
||||
// TODO logically the InternalVersion is different for every Group, so this structure
|
||||
// must be map
|
||||
InternalVersions map[string]unversioned.GroupVersion
|
||||
|
||||
// MetaInsertionFactory is used to create an object to store and retrieve
|
||||
// the version and kind information for all objects. The default uses the
|
||||
@ -61,13 +65,19 @@ type Scheme struct {
|
||||
// NewScheme manufactures a new scheme.
|
||||
func NewScheme() *Scheme {
|
||||
s := &Scheme{
|
||||
versionMap: map[string]map[string]reflect.Type{},
|
||||
typeToVersion: map[reflect.Type]string{},
|
||||
typeToKind: map[reflect.Type][]string{},
|
||||
converter: NewConverter(),
|
||||
cloner: NewCloner(),
|
||||
InternalVersion: "",
|
||||
MetaFactory: DefaultMetaFactory,
|
||||
versionMap: map[string]map[string]reflect.Type{},
|
||||
typeToVersion: map[reflect.Type]string{},
|
||||
typeToKind: map[reflect.Type][]string{},
|
||||
converter: NewConverter(),
|
||||
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"},
|
||||
},
|
||||
MetaFactory: DefaultMetaFactory,
|
||||
}
|
||||
s.converter.nameFunc = s.nameFunc
|
||||
return s
|
||||
@ -159,13 +169,21 @@ func (s *Scheme) KnownTypes(version string) map[string]reflect.Type {
|
||||
// NewObject returns a new object of the given version and name,
|
||||
// or an error if it hasn't been registered.
|
||||
func (s *Scheme) NewObject(gvString, kind string) (interface{}, error) {
|
||||
gv, err := unversioned.ParseGroupVersion(gvString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
gvk := gv.WithKind(kind)
|
||||
|
||||
if types, ok := s.versionMap[gvString]; ok {
|
||||
if t, ok := types[kind]; ok {
|
||||
return reflect.New(t).Interface(), nil
|
||||
}
|
||||
return nil, ¬RegisteredErr{kind: kind, version: gvString}
|
||||
|
||||
return nil, ¬RegisteredErr{gvk: gvk}
|
||||
}
|
||||
return nil, ¬RegisteredErr{kind: kind, version: gvString}
|
||||
|
||||
return nil, ¬RegisteredErr{gvk: gvk}
|
||||
}
|
||||
|
||||
// AddConversionFuncs adds functions to the list of conversion functions. The given
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
@ -118,7 +119,6 @@ func GetTestScheme() *Scheme {
|
||||
s.AddKnownTypeWithName("v1", "TestType2", &ExternalTestType2{})
|
||||
s.AddKnownTypeWithName("", "TestType3", &TestType1{})
|
||||
s.AddKnownTypeWithName("v1", "TestType3", &ExternalTestType1{})
|
||||
s.InternalVersion = ""
|
||||
s.MetaFactory = testMetaFactory{}
|
||||
return s
|
||||
}
|
||||
@ -361,7 +361,7 @@ func TestBadJSONRejection(t *testing.T) {
|
||||
|
||||
func TestBadJSONRejectionForSetInternalVersion(t *testing.T) {
|
||||
s := GetTestScheme()
|
||||
s.InternalVersion = "v1"
|
||||
s.InternalVersions[""] = unversioned.GroupVersion{Version: "v1"}
|
||||
badJSONs := [][]byte{
|
||||
[]byte(`{"myKindKey":"TestType1"}`), // Missing version
|
||||
}
|
||||
|
@ -88,7 +88,8 @@ func (g *conversionGenerator) AddImport(pkg string) string {
|
||||
|
||||
func (g *conversionGenerator) GenerateConversionsForType(version string, reflection reflect.Type) error {
|
||||
kind := reflection.Name()
|
||||
internalObj, err := g.scheme.NewObject(g.scheme.InternalVersion, kind)
|
||||
// TODO this is equivalent to what it did before, but it needs to be fixed for the proper group
|
||||
internalObj, err := g.scheme.NewObject(g.scheme.InternalVersions[""].String(), kind)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot create an object of type %v in internal version", kind)
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
)
|
||||
@ -61,11 +62,15 @@ func (*EmbeddedTest) IsAnAPIObject() {}
|
||||
func (*EmbeddedTestExternal) IsAnAPIObject() {}
|
||||
|
||||
func TestDecodeEmptyRawExtensionAsObject(t *testing.T) {
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes("", &ObjectTest{})
|
||||
s.AddKnownTypeWithName("v1test", "ObjectTest", &ObjectTestExternal{})
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
externalGVK := unversioned.GroupVersionKind{Group: "test.group", Version: "v1test", Kind: "ObjectTest"}
|
||||
|
||||
obj, err := s.Decode([]byte(`{"kind":"ObjectTest","apiVersion":"v1test","items":[{}]}`))
|
||||
s := runtime.NewScheme()
|
||||
s.AddInternalGroupVersion(internalGV)
|
||||
s.AddKnownTypes(internalGV.String(), &ObjectTest{})
|
||||
s.AddKnownTypeWithName(externalGVK.GroupVersion().String(), externalGVK.Kind, &ObjectTestExternal{})
|
||||
|
||||
obj, err := s.Decode([]byte(`{"kind":"` + externalGVK.Kind + `","apiVersion":"` + externalGVK.GroupVersion().String() + `","items":[{}]}`))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@ -74,7 +79,7 @@ func TestDecodeEmptyRawExtensionAsObject(t *testing.T) {
|
||||
t.Fatalf("unexpected object: %#v", test.Items[0])
|
||||
}
|
||||
|
||||
obj, err = s.Decode([]byte(`{"kind":"ObjectTest","apiVersion":"v1test","items":[{"kind":"Other","apiVersion":"v1"}]}`))
|
||||
obj, err = s.Decode([]byte(`{"kind":"` + externalGVK.Kind + `","apiVersion":"` + externalGVK.GroupVersion().String() + `","items":[{"kind":"Other","apiVersion":"v1"}]}`))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@ -85,11 +90,15 @@ func TestDecodeEmptyRawExtensionAsObject(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestArrayOfRuntimeObject(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "v1test"}
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes("", &EmbeddedTest{})
|
||||
s.AddKnownTypeWithName("v1test", "EmbeddedTest", &EmbeddedTestExternal{})
|
||||
s.AddKnownTypes("", &ObjectTest{})
|
||||
s.AddKnownTypeWithName("v1test", "ObjectTest", &ObjectTestExternal{})
|
||||
s.AddInternalGroupVersion(internalGV)
|
||||
s.AddKnownTypes(internalGV.String(), &EmbeddedTest{})
|
||||
s.AddKnownTypeWithName(externalGV.String(), "EmbeddedTest", &EmbeddedTestExternal{})
|
||||
s.AddKnownTypes(internalGV.String(), &ObjectTest{})
|
||||
s.AddKnownTypeWithName(externalGV.String(), "ObjectTest", &ObjectTestExternal{})
|
||||
|
||||
internal := &ObjectTest{
|
||||
Items: []runtime.Object{
|
||||
@ -104,7 +113,7 @@ func TestArrayOfRuntimeObject(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
wire, err := s.EncodeToVersion(internal, "v1test")
|
||||
wire, err := s.EncodeToVersion(internal, externalGV.String())
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@ -147,9 +156,14 @@ func TestArrayOfRuntimeObject(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEmbeddedObject(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "v1test"}
|
||||
embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest")
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes("", &EmbeddedTest{})
|
||||
s.AddKnownTypeWithName("v1test", "EmbeddedTest", &EmbeddedTestExternal{})
|
||||
s.AddInternalGroupVersion(internalGV)
|
||||
s.AddKnownTypes(internalGV.String(), &EmbeddedTest{})
|
||||
s.AddKnownTypeWithName(externalGV.String(), embeddedTestExternalGVK.Kind, &EmbeddedTestExternal{})
|
||||
|
||||
outer := &EmbeddedTest{
|
||||
ID: "outer",
|
||||
@ -160,7 +174,7 @@ func TestEmbeddedObject(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
wire, err := s.EncodeToVersion(outer, "v1test")
|
||||
wire, err := s.EncodeToVersion(outer, externalGV.String())
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected encode error '%v'", err)
|
||||
}
|
||||
@ -206,9 +220,14 @@ func TestEmbeddedObject(t *testing.T) {
|
||||
|
||||
// TestDeepCopyOfEmbeddedObject checks to make sure that EmbeddedObject's can be passed through DeepCopy with fidelity
|
||||
func TestDeepCopyOfEmbeddedObject(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "v1test"}
|
||||
embeddedTestExternalGVK := externalGV.WithKind("EmbeddedTest")
|
||||
|
||||
s := runtime.NewScheme()
|
||||
s.AddKnownTypes("", &EmbeddedTest{})
|
||||
s.AddKnownTypeWithName("v1test", "EmbeddedTest", &EmbeddedTestExternal{})
|
||||
s.AddInternalGroupVersion(internalGV)
|
||||
s.AddKnownTypes(internalGV.String(), &EmbeddedTest{})
|
||||
s.AddKnownTypeWithName(externalGV.String(), embeddedTestExternalGVK.Kind, &EmbeddedTestExternal{})
|
||||
|
||||
original := &EmbeddedTest{
|
||||
ID: "outer",
|
||||
@ -219,7 +238,7 @@ func TestDeepCopyOfEmbeddedObject(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
originalData, err := s.EncodeToVersion(original, "v1test")
|
||||
originalData, err := s.EncodeToVersion(original, externalGV.String())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
@ -230,7 +249,7 @@ func TestDeepCopyOfEmbeddedObject(t *testing.T) {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
copiedData, err := s.EncodeToVersion(copyOfOriginal.(runtime.Object), "v1test")
|
||||
copiedData, err := s.EncodeToVersion(copyOfOriginal.(runtime.Object), externalGV.String())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -181,8 +181,16 @@ func (self *Scheme) runtimeObjectToRawExtensionArray(in *[]Object, out *[]RawExt
|
||||
default:
|
||||
version := outVersion
|
||||
// if the object exists
|
||||
if inVersion, _, err := scheme.ObjectVersionAndKind(src[i]); err == nil && len(inVersion) != 0 {
|
||||
version = inVersion
|
||||
// this code is try to set the outputVersion, but only if the object has a non-internal group version
|
||||
if inGVString, _, err := scheme.ObjectVersionAndKind(src[i]); err == nil && len(inGVString) != 0 {
|
||||
inGV, err := unversioned.ParseGroupVersion(inGVString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if self.raw.InternalVersions[inGV.Group] != inGV {
|
||||
version = inGV.String()
|
||||
}
|
||||
}
|
||||
data, err := scheme.EncodeToVersion(src[i], version)
|
||||
if err != nil {
|
||||
@ -222,9 +230,13 @@ func (self *Scheme) rawExtensionToRuntimeObjectArray(in *[]RawExtension, out *[]
|
||||
}
|
||||
|
||||
// NewScheme creates a new Scheme. This scheme is pluggable by default.
|
||||
func NewScheme() *Scheme {
|
||||
func NewScheme(internalGroupVersions ...unversioned.GroupVersion) *Scheme {
|
||||
s := &Scheme{conversion.NewScheme(), map[string]map[string]FieldLabelConversionFunc{}}
|
||||
s.raw.InternalVersion = ""
|
||||
|
||||
for _, internalGV := range internalGroupVersions {
|
||||
s.raw.InternalVersions[internalGV.Group] = internalGV
|
||||
}
|
||||
|
||||
s.raw.MetaFactory = conversion.SimpleMetaFactory{BaseFields: []string{"TypeMeta"}, VersionField: "APIVersion", KindField: "Kind"}
|
||||
if err := s.raw.AddConversionFuncs(
|
||||
s.embeddedObjectToRawExtension,
|
||||
@ -247,6 +259,10 @@ func NewScheme() *Scheme {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Scheme) AddInternalGroupVersion(gv unversioned.GroupVersion) {
|
||||
s.raw.InternalVersions[gv.Group] = gv
|
||||
}
|
||||
|
||||
// AddKnownTypes registers the types of the arguments to the marshaller of the package api.
|
||||
// Encode() refuses the object unless its type is registered with AddKnownTypes.
|
||||
func (s *Scheme) AddKnownTypes(version string, types ...Object) {
|
||||
|
@ -44,12 +44,15 @@ func (*InternalSimple) IsAnAPIObject() {}
|
||||
func (*ExternalSimple) IsAnAPIObject() {}
|
||||
|
||||
func TestScheme(t *testing.T) {
|
||||
internalGVK := unversioned.GroupVersionKind{Group: "test.group", Version: "", Kind: "Simple"}
|
||||
externalGVK := unversioned.GroupVersionKind{Group: "test.group", Version: "externalVersion", Kind: "Simple"}
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
internalGVK := internalGV.WithKind("Simple")
|
||||
externalGVK := externalGV.WithKind("Simple")
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName(internalGVK.GroupVersion().String(), internalGVK.Kind, &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName(externalGVK.GroupVersion().String(), externalGVK.Kind, &ExternalSimple{})
|
||||
scheme.AddInternalGroupVersion(internalGV)
|
||||
scheme.AddKnownTypeWithName(internalGV.String(), internalGVK.Kind, &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName(externalGV.String(), externalGVK.Kind, &ExternalSimple{})
|
||||
|
||||
// test that scheme is an ObjectTyper
|
||||
var _ runtime.ObjectTyper = scheme
|
||||
@ -60,10 +63,10 @@ func TestScheme(t *testing.T) {
|
||||
// Register functions to verify that scope.Meta() gets set correctly.
|
||||
err := scheme.AddConversionFuncs(
|
||||
func(in *InternalSimple, out *ExternalSimple, scope conversion.Scope) error {
|
||||
if e, a := internalGVK.GroupVersion().String(), scope.Meta().SrcVersion; e != a {
|
||||
if e, a := internalGV.String(), scope.Meta().SrcVersion; e != a {
|
||||
t.Errorf("Expected '%v', got '%v'", e, a)
|
||||
}
|
||||
if e, a := externalGVK.GroupVersion().String(), scope.Meta().DestVersion; e != a {
|
||||
if e, a := externalGV.String(), scope.Meta().DestVersion; e != a {
|
||||
t.Errorf("Expected '%v', got '%v'", e, a)
|
||||
}
|
||||
scope.Convert(&in.TypeMeta, &out.TypeMeta, 0)
|
||||
@ -72,10 +75,10 @@ func TestScheme(t *testing.T) {
|
||||
return nil
|
||||
},
|
||||
func(in *ExternalSimple, out *InternalSimple, scope conversion.Scope) error {
|
||||
if e, a := externalGVK.GroupVersion().String(), scope.Meta().SrcVersion; e != a {
|
||||
if e, a := externalGV.String(), scope.Meta().SrcVersion; e != a {
|
||||
t.Errorf("Expected '%v', got '%v'", e, a)
|
||||
}
|
||||
if e, a := internalGVK.GroupVersion().String(), scope.Meta().DestVersion; e != a {
|
||||
if e, a := internalGV.String(), scope.Meta().DestVersion; e != a {
|
||||
t.Errorf("Expected '%v', got '%v'", e, a)
|
||||
}
|
||||
scope.Convert(&in.TypeMeta, &out.TypeMeta, 0)
|
||||
@ -93,11 +96,11 @@ func TestScheme(t *testing.T) {
|
||||
|
||||
// Test Encode, Decode, DecodeInto, and DecodeToVersion
|
||||
obj := runtime.Object(simple)
|
||||
data, err := scheme.EncodeToVersion(obj, "externalVersion")
|
||||
data, err := scheme.EncodeToVersion(obj, externalGV.String())
|
||||
obj2, err2 := scheme.Decode(data)
|
||||
obj3 := &InternalSimple{}
|
||||
err3 := scheme.DecodeInto(data, obj3)
|
||||
obj4, err4 := scheme.DecodeToVersion(data, externalGVK.GroupVersion())
|
||||
obj4, err4 := scheme.DecodeToVersion(data, externalGV)
|
||||
if err != nil || err2 != nil || err3 != nil || err4 != nil {
|
||||
t.Fatalf("Failure: '%v' '%v' '%v' '%v'", err, err2, err3, err4)
|
||||
}
|
||||
@ -202,9 +205,13 @@ func (*ExternalOptionalExtensionType) IsAnAPIObject() {}
|
||||
func (*InternalOptionalExtensionType) IsAnAPIObject() {}
|
||||
|
||||
func TestExternalToInternalMapping(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName("", "OptionalExtensionType", &InternalOptionalExtensionType{})
|
||||
scheme.AddKnownTypeWithName("testExternal", "OptionalExtensionType", &ExternalOptionalExtensionType{})
|
||||
scheme.AddInternalGroupVersion(internalGV)
|
||||
scheme.AddKnownTypeWithName(internalGV.String(), "OptionalExtensionType", &InternalOptionalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(externalGV.String(), "OptionalExtensionType", &ExternalOptionalExtensionType{})
|
||||
|
||||
table := []struct {
|
||||
obj runtime.Object
|
||||
@ -212,7 +219,7 @@ func TestExternalToInternalMapping(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
&InternalOptionalExtensionType{Extension: runtime.EmbeddedObject{Object: nil}},
|
||||
`{"kind":"OptionalExtensionType","apiVersion":"testExternal"}`,
|
||||
`{"kind":"OptionalExtensionType","apiVersion":"` + externalGV.String() + `"}`,
|
||||
},
|
||||
}
|
||||
|
||||
@ -234,15 +241,19 @@ func TestExternalToInternalMapping(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExtensionMapping(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName("", "ExtensionType", &InternalExtensionType{})
|
||||
scheme.AddKnownTypeWithName("", "OptionalExtensionType", &InternalOptionalExtensionType{})
|
||||
scheme.AddKnownTypeWithName("", "A", &ExtensionA{})
|
||||
scheme.AddKnownTypeWithName("", "B", &ExtensionB{})
|
||||
scheme.AddKnownTypeWithName("testExternal", "ExtensionType", &ExternalExtensionType{})
|
||||
scheme.AddKnownTypeWithName("testExternal", "OptionalExtensionType", &ExternalOptionalExtensionType{})
|
||||
scheme.AddKnownTypeWithName("testExternal", "A", &ExtensionA{})
|
||||
scheme.AddKnownTypeWithName("testExternal", "B", &ExtensionB{})
|
||||
scheme.AddInternalGroupVersion(internalGV)
|
||||
scheme.AddKnownTypeWithName(internalGV.String(), "ExtensionType", &InternalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(internalGV.String(), "OptionalExtensionType", &InternalOptionalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(internalGV.String(), "A", &ExtensionA{})
|
||||
scheme.AddKnownTypeWithName(internalGV.String(), "B", &ExtensionB{})
|
||||
scheme.AddKnownTypeWithName(externalGV.String(), "ExtensionType", &ExternalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(externalGV.String(), "OptionalExtensionType", &ExternalOptionalExtensionType{})
|
||||
scheme.AddKnownTypeWithName(externalGV.String(), "A", &ExtensionA{})
|
||||
scheme.AddKnownTypeWithName(externalGV.String(), "B", &ExtensionB{})
|
||||
|
||||
table := []struct {
|
||||
obj runtime.Object
|
||||
@ -250,21 +261,21 @@ func TestExtensionMapping(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
&InternalExtensionType{Extension: runtime.EmbeddedObject{Object: &ExtensionA{TestString: "foo"}}},
|
||||
`{"kind":"ExtensionType","apiVersion":"testExternal","extension":{"kind":"A","testString":"foo"}}
|
||||
`{"kind":"ExtensionType","apiVersion":"` + externalGV.String() + `","extension":{"kind":"A","testString":"foo"}}
|
||||
`,
|
||||
}, {
|
||||
&InternalExtensionType{Extension: runtime.EmbeddedObject{Object: &ExtensionB{TestString: "bar"}}},
|
||||
`{"kind":"ExtensionType","apiVersion":"testExternal","extension":{"kind":"B","testString":"bar"}}
|
||||
`{"kind":"ExtensionType","apiVersion":"` + externalGV.String() + `","extension":{"kind":"B","testString":"bar"}}
|
||||
`,
|
||||
}, {
|
||||
&InternalExtensionType{Extension: runtime.EmbeddedObject{Object: nil}},
|
||||
`{"kind":"ExtensionType","apiVersion":"testExternal","extension":null}
|
||||
`{"kind":"ExtensionType","apiVersion":"` + externalGV.String() + `","extension":null}
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, item := range table {
|
||||
gotEncoded, err := scheme.EncodeToVersion(item.obj, "testExternal")
|
||||
gotEncoded, err := scheme.EncodeToVersion(item.obj, externalGV.String())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error '%v' (%#v)", err, item.obj)
|
||||
} else if e, a := item.encoded, string(gotEncoded); e != a {
|
||||
@ -288,10 +299,14 @@ func TestExtensionMapping(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestEncode(t *testing.T) {
|
||||
internalGV := unversioned.GroupVersion{Group: "test.group", Version: ""}
|
||||
externalGV := unversioned.GroupVersion{Group: "test.group", Version: "testExternal"}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypeWithName("", "Simple", &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName("externalVersion", "Simple", &ExternalSimple{})
|
||||
codec := runtime.CodecFor(scheme, "externalVersion")
|
||||
scheme.AddInternalGroupVersion(internalGV)
|
||||
scheme.AddKnownTypeWithName(internalGV.String(), "Simple", &InternalSimple{})
|
||||
scheme.AddKnownTypeWithName(externalGV.String(), "Simple", &ExternalSimple{})
|
||||
codec := runtime.CodecFor(scheme, externalGV.String())
|
||||
test := &InternalSimple{
|
||||
TestString: "I'm the same",
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user