diff --git a/pkg/apimachinery/types.go b/pkg/apimachinery/types.go index 0e90cbbe321..d42323651ac 100644 --- a/pkg/apimachinery/types.go +++ b/pkg/apimachinery/types.go @@ -17,6 +17,8 @@ limitations under the License. package apimachinery import ( + "fmt" + "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/runtime" @@ -47,6 +49,36 @@ type GroupMeta struct { RESTMapper meta.RESTMapper // InterfacesFor returns the default Codec and ResourceVersioner for a given version - // or an error if the version is not known. + // string, or an error if the version is not known. + // TODO: make this stop being a func pointer and always use the default + // function provided below once every place that populates this field has been changed. InterfacesFor func(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) + + // InterfacesByVersion stores the per-version interfaces. + InterfacesByVersion map[unversioned.GroupVersion]*meta.VersionInterfaces +} + +// InterfacesFor returns the default Codec and ResourceVersioner for a given version +// string, or an error if the version is not known. +// TODO: Remove the "Default" prefix. +func (gm *GroupMeta) DefaultInterfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, error) { + if v, ok := gm.InterfacesByVersion[version]; ok { + return v, nil + } + return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, gm.GroupVersions) +} + +// Adds the given version to the group. Only call during init, after that +// GroupMeta objects should be immutable. Not thread safe. +// (If you use this, be sure to set .InterfacesFor = .DefaultInterfacesFor) +func (gm *GroupMeta) AddVersion(version unversioned.GroupVersion, interfaces *meta.VersionInterfaces) error { + if e, a := gm.GroupVersion.Group, version.Group; a != e { + return fmt.Errorf("got a version in group %v, but am in group %v", a, e) + } + if gm.InterfacesByVersion == nil { + gm.InterfacesByVersion = make(map[unversioned.GroupVersion]*meta.VersionInterfaces) + } + gm.InterfacesByVersion[version] = interfaces + gm.GroupVersions = append(gm.GroupVersions, version) + return nil } diff --git a/pkg/apimachinery/types_test.go b/pkg/apimachinery/types_test.go new file mode 100644 index 00000000000..7cf0e918abe --- /dev/null +++ b/pkg/apimachinery/types_test.go @@ -0,0 +1,43 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apimachinery + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api/unversioned" +) + +func TestAdd(t *testing.T) { + gm := GroupMeta{ + GroupVersion: unversioned.GroupVersion{ + Group: "test", + Version: "v1", + }, + GroupVersions: []unversioned.GroupVersion{{"test", "v1"}}, + } + + gm.AddVersion(unversioned.GroupVersion{"test", "v1"}, nil) + if e, a := 1, len(gm.InterfacesByVersion); e != a { + t.Errorf("expected %v, got %v") + } + + // GroupVersions is unchanged + if e, a := 1, len(gm.GroupVersions); e != a { + t.Errorf("expected %v, got %v", e, a) + } +}