Commit d3b869ae authored by k8s-merge-robot's avatar k8s-merge-robot

Merge pull request #17922 from smarterclayton/split_codec

Auto commit by PR queue bot
parents 1992fca6 3262d8ef
...@@ -15,10 +15,12 @@ ...@@ -15,10 +15,12 @@
"nickname": "getAPIVersions", "nickname": "getAPIVersions",
"parameters": [], "parameters": [],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"application/json" "application/json",
"application/yaml"
] ]
} }
] ]
......
...@@ -15,10 +15,12 @@ ...@@ -15,10 +15,12 @@
"nickname": "getAPIVersions", "nickname": "getAPIVersions",
"parameters": [], "parameters": [],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"application/json" "application/json",
"application/yaml"
] ]
} }
] ]
......
...@@ -15,10 +15,12 @@ ...@@ -15,10 +15,12 @@
"nickname": "getAPIGroup", "nickname": "getAPIGroup",
"parameters": [], "parameters": [],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"application/json" "application/json",
"application/yaml"
] ]
} }
] ]
......
...@@ -79,7 +79,8 @@ ...@@ -79,7 +79,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -124,7 +125,8 @@ ...@@ -124,7 +125,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -201,7 +203,8 @@ ...@@ -201,7 +203,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -351,7 +354,8 @@ ...@@ -351,7 +354,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -404,7 +408,8 @@ ...@@ -404,7 +408,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -457,7 +462,8 @@ ...@@ -457,7 +462,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"application/json-patch+json", "application/json-patch+json",
...@@ -512,7 +518,8 @@ ...@@ -512,7 +518,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -678,7 +685,8 @@ ...@@ -678,7 +685,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -836,7 +844,8 @@ ...@@ -836,7 +844,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -881,7 +890,8 @@ ...@@ -881,7 +890,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -958,7 +968,8 @@ ...@@ -958,7 +968,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -1108,7 +1119,8 @@ ...@@ -1108,7 +1119,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -1161,7 +1173,8 @@ ...@@ -1161,7 +1173,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -1214,7 +1227,8 @@ ...@@ -1214,7 +1227,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"application/json-patch+json", "application/json-patch+json",
...@@ -1269,7 +1283,8 @@ ...@@ -1269,7 +1283,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -1435,7 +1450,8 @@ ...@@ -1435,7 +1450,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -1569,7 +1585,8 @@ ...@@ -1569,7 +1585,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -1652,7 +1669,8 @@ ...@@ -1652,7 +1669,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -1697,7 +1715,8 @@ ...@@ -1697,7 +1715,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -1774,7 +1793,8 @@ ...@@ -1774,7 +1793,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -1924,7 +1944,8 @@ ...@@ -1924,7 +1944,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -1977,7 +1998,8 @@ ...@@ -1977,7 +1998,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -2030,7 +2052,8 @@ ...@@ -2030,7 +2052,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"application/json-patch+json", "application/json-patch+json",
...@@ -2085,7 +2108,8 @@ ...@@ -2085,7 +2108,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -2251,7 +2275,8 @@ ...@@ -2251,7 +2275,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -2385,7 +2410,8 @@ ...@@ -2385,7 +2410,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -2468,7 +2494,8 @@ ...@@ -2468,7 +2494,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -2513,7 +2540,8 @@ ...@@ -2513,7 +2540,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -2590,7 +2618,8 @@ ...@@ -2590,7 +2618,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -2740,7 +2769,8 @@ ...@@ -2740,7 +2769,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -2793,7 +2823,8 @@ ...@@ -2793,7 +2823,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -2846,7 +2877,8 @@ ...@@ -2846,7 +2877,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"application/json-patch+json", "application/json-patch+json",
...@@ -2901,7 +2933,8 @@ ...@@ -2901,7 +2933,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -3067,7 +3100,8 @@ ...@@ -3067,7 +3100,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -3201,7 +3235,8 @@ ...@@ -3201,7 +3235,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -3252,7 +3287,8 @@ ...@@ -3252,7 +3287,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -3305,7 +3341,8 @@ ...@@ -3305,7 +3341,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"*/*" "*/*"
...@@ -3358,7 +3395,8 @@ ...@@ -3358,7 +3395,8 @@
} }
], ],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"application/json-patch+json", "application/json-patch+json",
...@@ -3379,10 +3417,12 @@ ...@@ -3379,10 +3417,12 @@
"nickname": "getAPIResources", "nickname": "getAPIResources",
"parameters": [], "parameters": [],
"produces": [ "produces": [
"application/json" "application/json",
"application/yaml"
], ],
"consumes": [ "consumes": [
"application/json" "application/json",
"application/yaml"
] ]
} }
] ]
......
...@@ -61,7 +61,7 @@ func pkgPath(group, version string) string { ...@@ -61,7 +61,7 @@ func pkgPath(group, version string) string {
group = "api" group = "api"
} }
gv := group gv := group
if version != "" { if version != "__internal" {
gv = path.Join(group, version) gv = path.Join(group, version)
} }
switch { switch {
...@@ -104,7 +104,7 @@ func main() { ...@@ -104,7 +104,7 @@ func main() {
} else { } else {
pkgname = gv.Group pkgname = gv.Group
} }
if len(gv.Version) != 0 { if len(gv.Version) != 0 && gv.Version != kruntime.APIVersionInternal {
pkgname = gv.Version pkgname = gv.Version
} }
......
...@@ -26,7 +26,7 @@ import ( ...@@ -26,7 +26,7 @@ import (
"net/http/httptest" "net/http/httptest"
"os" "os"
"reflect" "reflect"
"runtime" gruntime "runtime"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
...@@ -52,6 +52,7 @@ import ( ...@@ -52,6 +52,7 @@ import (
kubetypes "k8s.io/kubernetes/pkg/kubelet/types" kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/master" "k8s.io/kubernetes/pkg/master"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
utilnet "k8s.io/kubernetes/pkg/util/net" utilnet "k8s.io/kubernetes/pkg/util/net"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/sets"
...@@ -444,7 +445,7 @@ func runReplicationControllerTest(c *client.Client) { ...@@ -444,7 +445,7 @@ func runReplicationControllerTest(c *client.Client) {
glog.Infof("Done reading config file, took %v", time.Since(t)) glog.Infof("Done reading config file, took %v", time.Since(t))
t = time.Now() t = time.Now()
var controller api.ReplicationController var controller api.ReplicationController
if err := api.Scheme.DecodeInto(data, &controller); err != nil { if err := runtime.DecodeInto(testapi.Default.Codec(), data, &controller); err != nil {
glog.Fatalf("Unexpected error: %v", err) glog.Fatalf("Unexpected error: %v", err)
} }
...@@ -958,7 +959,7 @@ func addFlags(fs *pflag.FlagSet) { ...@@ -958,7 +959,7 @@ func addFlags(fs *pflag.FlagSet) {
} }
func main() { func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) gruntime.GOMAXPROCS(gruntime.NumCPU())
addFlags(pflag.CommandLine) addFlags(pflag.CommandLine)
util.InitFlags() util.InitFlags()
......
...@@ -34,7 +34,6 @@ import ( ...@@ -34,7 +34,6 @@ import (
"k8s.io/kubernetes/cmd/kube-apiserver/app/options" "k8s.io/kubernetes/cmd/kube-apiserver/app/options"
"k8s.io/kubernetes/pkg/admission" "k8s.io/kubernetes/pkg/admission"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
apiutil "k8s.io/kubernetes/pkg/api/util" apiutil "k8s.io/kubernetes/pkg/api/util"
"k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apimachinery/registered"
...@@ -48,6 +47,7 @@ import ( ...@@ -48,6 +47,7 @@ import (
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client" kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
"k8s.io/kubernetes/pkg/master" "k8s.io/kubernetes/pkg/master"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/serviceaccount" "k8s.io/kubernetes/pkg/serviceaccount"
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
...@@ -82,9 +82,9 @@ func verifyClusterIPFlags(s *options.APIServer) { ...@@ -82,9 +82,9 @@ func verifyClusterIPFlags(s *options.APIServer) {
} }
} }
type newEtcdFunc func([]string, meta.VersionInterfacesFunc, string, string) (storage.Interface, error) type newEtcdFunc func([]string, runtime.NegotiatedSerializer, string, string) (storage.Interface, error)
func newEtcd(etcdServerList []string, interfacesFunc meta.VersionInterfacesFunc, storageGroupVersionString, pathPrefix string) (etcdStorage storage.Interface, err error) { func newEtcd(etcdServerList []string, ns runtime.NegotiatedSerializer, storageGroupVersionString, pathPrefix string) (etcdStorage storage.Interface, err error) {
if storageGroupVersionString == "" { if storageGroupVersionString == "" {
return etcdStorage, fmt.Errorf("storageVersion is required to create a etcd storage") return etcdStorage, fmt.Errorf("storageVersion is required to create a etcd storage")
} }
...@@ -96,11 +96,11 @@ func newEtcd(etcdServerList []string, interfacesFunc meta.VersionInterfacesFunc, ...@@ -96,11 +96,11 @@ func newEtcd(etcdServerList []string, interfacesFunc meta.VersionInterfacesFunc,
var storageConfig etcdstorage.EtcdConfig var storageConfig etcdstorage.EtcdConfig
storageConfig.ServerList = etcdServerList storageConfig.ServerList = etcdServerList
storageConfig.Prefix = pathPrefix storageConfig.Prefix = pathPrefix
versionedInterface, err := interfacesFunc(storageVersion) s, ok := ns.SerializerForMediaType("application/json", nil)
if err != nil { if !ok {
return nil, err return nil, fmt.Errorf("unable to find serializer for JSON")
} }
storageConfig.Codec = versionedInterface.Codec storageConfig.Codec = runtime.NewCodec(ns.EncoderForVersion(s, storageVersion), ns.DecoderToVersion(s, unversioned.GroupVersion{Group: storageVersion.Group, Version: runtime.APIVersionInternal}))
return storageConfig.NewStorage() return storageConfig.NewStorage()
} }
...@@ -149,7 +149,7 @@ func updateEtcdOverrides(overrides []string, storageVersions map[string]string, ...@@ -149,7 +149,7 @@ func updateEtcdOverrides(overrides []string, storageVersions map[string]string,
} }
servers := strings.Split(tokens[1], ";") servers := strings.Split(tokens[1], ";")
etcdOverrideStorage, err := newEtcdFn(servers, apigroup.InterfacesFor, storageVersions[apigroup.GroupVersion.Group], prefix) etcdOverrideStorage, err := newEtcdFn(servers, api.Codecs, storageVersions[apigroup.GroupVersion.Group], prefix)
if err != nil { if err != nil {
glog.Fatalf("Invalid storage version or misconfigured etcd for %s: %v", tokens[0], err) glog.Fatalf("Invalid storage version or misconfigured etcd for %s: %v", tokens[0], err)
} }
...@@ -260,7 +260,7 @@ func Run(s *options.APIServer) error { ...@@ -260,7 +260,7 @@ func Run(s *options.APIServer) error {
if _, found := storageVersions[legacyV1Group.GroupVersion.Group]; !found { if _, found := storageVersions[legacyV1Group.GroupVersion.Group]; !found {
glog.Fatalf("Couldn't find the storage version for group: %q in storageVersions: %v", legacyV1Group.GroupVersion.Group, storageVersions) glog.Fatalf("Couldn't find the storage version for group: %q in storageVersions: %v", legacyV1Group.GroupVersion.Group, storageVersions)
} }
etcdStorage, err := newEtcd(s.EtcdServerList, legacyV1Group.InterfacesFor, storageVersions[legacyV1Group.GroupVersion.Group], s.EtcdPathPrefix) etcdStorage, err := newEtcd(s.EtcdServerList, api.Codecs, storageVersions[legacyV1Group.GroupVersion.Group], s.EtcdPathPrefix)
if err != nil { if err != nil {
glog.Fatalf("Invalid storage version or misconfigured etcd: %v", err) glog.Fatalf("Invalid storage version or misconfigured etcd: %v", err)
} }
...@@ -274,7 +274,7 @@ func Run(s *options.APIServer) error { ...@@ -274,7 +274,7 @@ func Run(s *options.APIServer) error {
if _, found := storageVersions[expGroup.GroupVersion.Group]; !found { if _, found := storageVersions[expGroup.GroupVersion.Group]; !found {
glog.Fatalf("Couldn't find the storage version for group: %q in storageVersions: %v", expGroup.GroupVersion.Group, storageVersions) glog.Fatalf("Couldn't find the storage version for group: %q in storageVersions: %v", expGroup.GroupVersion.Group, storageVersions)
} }
expEtcdStorage, err := newEtcd(s.EtcdServerList, expGroup.InterfacesFor, storageVersions[expGroup.GroupVersion.Group], s.EtcdPathPrefix) expEtcdStorage, err := newEtcd(s.EtcdServerList, api.Codecs, storageVersions[expGroup.GroupVersion.Group], s.EtcdPathPrefix)
if err != nil { if err != nil {
glog.Fatalf("Invalid extensions storage version or misconfigured etcd: %v", err) glog.Fatalf("Invalid extensions storage version or misconfigured etcd: %v", err)
} }
...@@ -381,6 +381,7 @@ func Run(s *options.APIServer) error { ...@@ -381,6 +381,7 @@ func Run(s *options.APIServer) error {
ProxyTLSClientConfig: proxyTLSClientConfig, ProxyTLSClientConfig: proxyTLSClientConfig,
ServiceNodePortRange: s.ServiceNodePortRange, ServiceNodePortRange: s.ServiceNodePortRange,
KubernetesServiceNodePort: s.KubernetesServiceNodePort, KubernetesServiceNodePort: s.KubernetesServiceNodePort,
Serializer: api.Codecs,
}, },
EnableCoreControllers: true, EnableCoreControllers: true,
EventTTL: s.EventTTL, EventTTL: s.EventTTL,
......
...@@ -24,9 +24,9 @@ import ( ...@@ -24,9 +24,9 @@ import (
"k8s.io/kubernetes/cmd/kube-apiserver/app/options" "k8s.io/kubernetes/cmd/kube-apiserver/app/options"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/genericapiserver" "k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
) )
...@@ -133,7 +133,7 @@ func TestUpdateEtcdOverrides(t *testing.T) { ...@@ -133,7 +133,7 @@ func TestUpdateEtcdOverrides(t *testing.T) {
} }
for _, test := range testCases { for _, test := range testCases {
newEtcd := func(serverList []string, _ meta.VersionInterfacesFunc, _, _ string) (storage.Interface, error) { newEtcd := func(serverList []string, _ runtime.NegotiatedSerializer, _, _ string) (storage.Interface, error) {
if !reflect.DeepEqual(test.servers, serverList) { if !reflect.DeepEqual(test.servers, serverList) {
t.Errorf("unexpected server list, expected: %#v, got: %#v", test.servers, serverList) t.Errorf("unexpected server list, expected: %#v, got: %#v", test.servers, serverList)
} }
......
...@@ -48,13 +48,14 @@ func (g *genGroup) Namers(c *generator.Context) namer.NameSystems { ...@@ -48,13 +48,14 @@ func (g *genGroup) Namers(c *generator.Context) namer.NameSystems {
} }
func (g *genGroup) Imports(c *generator.Context) (imports []string) { func (g *genGroup) Imports(c *generator.Context) (imports []string) {
return append(g.imports.ImportLines(), "fmt") return g.imports.ImportLines()
} }
func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error { func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
sw := generator.NewSnippetWriter(w, c, "$", "$") sw := generator.NewSnippetWriter(w, c, "$", "$")
const pkgUnversioned = "k8s.io/kubernetes/pkg/client/unversioned" const pkgUnversioned = "k8s.io/kubernetes/pkg/client/unversioned"
const pkgRegistered = "k8s.io/kubernetes/pkg/apimachinery/registered" const pkgRegistered = "k8s.io/kubernetes/pkg/apimachinery/registered"
const pkgAPI = "k8s.io/kubernetes/pkg/api"
apiPath := func(group string) string { apiPath := func(group string) string {
if group == "legacy" { if group == "legacy" {
return `"/api"` return `"/api"`
...@@ -81,6 +82,7 @@ func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer ...@@ -81,6 +82,7 @@ func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer
"latestGroup": c.Universe.Variable(types.Name{Package: pkgRegistered, Name: "Group"}), "latestGroup": c.Universe.Variable(types.Name{Package: pkgRegistered, Name: "Group"}),
"GroupOrDie": c.Universe.Variable(types.Name{Package: pkgRegistered, Name: "GroupOrDie"}), "GroupOrDie": c.Universe.Variable(types.Name{Package: pkgRegistered, Name: "GroupOrDie"}),
"apiPath": apiPath(g.group), "apiPath": apiPath(g.group),
"latestCodecs": c.Universe.Variable(types.Name{Package: pkgAPI, Name: "Codecs"}),
} }
sw.Do(groupInterfaceTemplate, m) sw.Do(groupInterfaceTemplate, m)
sw.Do(groupClientTemplate, m) sw.Do(groupClientTemplate, m)
...@@ -181,12 +183,7 @@ func setConfigDefaults(config *$.Config|raw$) error { ...@@ -181,12 +183,7 @@ func setConfigDefaults(config *$.Config|raw$) error {
config.GroupVersion = &copyGroupVersion config.GroupVersion = &copyGroupVersion
//} //}
versionInterfaces, err := g.InterfacesFor(*config.GroupVersion) config.Codec = $.latestCodecs|raw$.LegacyCodec(*config.GroupVersion)
if err != nil {
return fmt.Errorf("$.Group$ API version '%s' is not recognized (valid values: %s)",
config.GroupVersion, g.GroupVersions)
}
config.Codec = versionInterfaces.Codec
if config.QPS == 0 { if config.QPS == 0 {
config.QPS = 5 config.QPS = 5
} }
......
...@@ -68,7 +68,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error { ...@@ -68,7 +68,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error {
groupMeta := apimachinery.GroupMeta{ groupMeta := apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion, GroupVersion: preferredExternalVersion,
GroupVersions: externalVersions, GroupVersions: externalVersions,
Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion),
RESTMapper: newRESTMapper(externalVersions), RESTMapper: newRESTMapper(externalVersions),
SelfLinker: runtime.SelfLinker(accessor), SelfLinker: runtime.SelfLinker(accessor),
InterfacesFor: interfacesFor, InterfacesFor: interfacesFor,
...@@ -97,7 +96,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e ...@@ -97,7 +96,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e
switch version { switch version {
case v1.SchemeGroupVersion: case v1.SchemeGroupVersion:
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
Codec: v1.Codec,
ObjectConvertor: api.Scheme, ObjectConvertor: api.Scheme,
MetadataAccessor: accessor, MetadataAccessor: accessor,
}, nil }, nil
......
...@@ -22,7 +22,7 @@ import ( ...@@ -22,7 +22,7 @@ import (
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
var SchemeGroupVersion = unversioned.GroupVersion{Group: "testgroup", Version: ""} var SchemeGroupVersion = unversioned.GroupVersion{Group: "testgroup", Version: runtime.APIVersionInternal}
func AddToScheme(scheme *runtime.Scheme) { func AddToScheme(scheme *runtime.Scheme) {
// Add the API to Scheme. // Add the API to Scheme.
......
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package v1 package v1
import ( import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
...@@ -25,8 +24,6 @@ import ( ...@@ -25,8 +24,6 @@ import (
var SchemeGroupVersion = unversioned.GroupVersion{Group: "testgroup", Version: "v1"} var SchemeGroupVersion = unversioned.GroupVersion{Group: "testgroup", Version: "v1"}
var Codec = runtime.CodecFor(api.Scheme, SchemeGroupVersion)
func AddToScheme(scheme *runtime.Scheme) { func AddToScheme(scheme *runtime.Scheme) {
// Add the API to Scheme. // Add the API to Scheme.
addKnownTypes(scheme) addKnownTypes(scheme)
......
...@@ -17,7 +17,7 @@ limitations under the License. ...@@ -17,7 +17,7 @@ limitations under the License.
package unversioned package unversioned
import ( import (
"fmt" api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered" registered "k8s.io/kubernetes/pkg/apimachinery/registered"
unversioned "k8s.io/kubernetes/pkg/client/unversioned" unversioned "k8s.io/kubernetes/pkg/client/unversioned"
) )
...@@ -79,12 +79,7 @@ func setConfigDefaults(config *unversioned.Config) error { ...@@ -79,12 +79,7 @@ func setConfigDefaults(config *unversioned.Config) error {
config.GroupVersion = &copyGroupVersion config.GroupVersion = &copyGroupVersion
//} //}
versionInterfaces, err := g.InterfacesFor(*config.GroupVersion) config.Codec = api.Codecs.LegacyCodec(*config.GroupVersion)
if err != nil {
return fmt.Errorf("Testgroup API version '%s' is not recognized (valid values: %s)",
config.GroupVersion, g.GroupVersions)
}
config.Codec = versionInterfaces.Codec
if config.QPS == 0 { if config.QPS == 0 {
config.QPS = 5 config.QPS = 5
} }
......
...@@ -40,7 +40,7 @@ func init() { ...@@ -40,7 +40,7 @@ func init() {
return return
} }
testapi.Groups[testgroup.SchemeGroupVersion.Group] = testapi.NewTestGroup( testapi.Groups[testgroup.SchemeGroupVersion.Group] = testapi.NewTestGroup(
unversioned.GroupVersion{Group: testgroup.SchemeGroupVersion.Group, Version: registered.GroupOrDie(testgroup.SchemeGroupVersion.Group).GroupVersion.Version}, registered.GroupOrDie(testgroup.SchemeGroupVersion.Group).GroupVersion,
testgroup.SchemeGroupVersion) testgroup.SchemeGroupVersion)
testHelper = testapi.Groups[testgroup.SchemeGroupVersion.Group] testHelper = testapi.Groups[testgroup.SchemeGroupVersion.Group]
} }
......
...@@ -42,6 +42,7 @@ import ( ...@@ -42,6 +42,7 @@ import (
client "k8s.io/kubernetes/pkg/client/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/dockertools"
kruntime "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
) )
...@@ -343,7 +344,7 @@ func (k *Executor) LaunchTask(driver bindings.ExecutorDriver, taskInfo *mesos.Ta ...@@ -343,7 +344,7 @@ func (k *Executor) LaunchTask(driver bindings.ExecutorDriver, taskInfo *mesos.Ta
return return
} }
obj, err := api.Codec.Decode(taskInfo.GetData()) obj, err := kruntime.Decode(api.Codecs.UniversalDecoder(), taskInfo.GetData())
if err != nil { if err != nil {
log.Errorf("failed to extract yaml data from the taskInfo.data %v", err) log.Errorf("failed to extract yaml data from the taskInfo.data %v", err)
k.sendStatus(driver, newStatus(taskInfo.GetTaskId(), mesos.TaskState_TASK_FAILED, k.sendStatus(driver, newStatus(taskInfo.GetTaskId(), mesos.TaskState_TASK_FAILED,
......
...@@ -211,7 +211,7 @@ func TestExecutorLaunchAndKillTask(t *testing.T) { ...@@ -211,7 +211,7 @@ func TestExecutorLaunchAndKillTask(t *testing.T) {
taskInfo, err := podTask.BuildTaskInfo() taskInfo, err := podTask.BuildTaskInfo()
assert.Equal(t, nil, err, "must be able to build task info") assert.Equal(t, nil, err, "must be able to build task info")
data, err := testapi.Default.Codec().Encode(pod) data, err := runtime.Encode(testapi.Default.Codec(), pod)
assert.Equal(t, nil, err, "must be able to encode a pod's spec data") assert.Equal(t, nil, err, "must be able to encode a pod's spec data")
taskInfo.Data = data taskInfo.Data = data
...@@ -410,7 +410,7 @@ func TestExecutorFrameworkMessage(t *testing.T) { ...@@ -410,7 +410,7 @@ func TestExecutorFrameworkMessage(t *testing.T) {
taskInfo, err := podTask.BuildTaskInfo() taskInfo, err := podTask.BuildTaskInfo()
assert.Equal(t, nil, err, "must be able to build task info") assert.Equal(t, nil, err, "must be able to build task info")
data, _ := testapi.Default.Codec().Encode(pod) data, _ := runtime.Encode(testapi.Default.Codec(), pod)
taskInfo.Data = data taskInfo.Data = data
mockDriver.On( mockDriver.On(
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
_ "k8s.io/kubernetes/pkg/api/install" _ "k8s.io/kubernetes/pkg/api/install"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime"
) )
func Gzip(pods <-chan *api.Pod) ([]byte, error) { func Gzip(pods <-chan *api.Pod) ([]byte, error) {
...@@ -32,7 +33,7 @@ func Gzip(pods <-chan *api.Pod) ([]byte, error) { ...@@ -32,7 +33,7 @@ func Gzip(pods <-chan *api.Pod) ([]byte, error) {
} }
func gzipList(list *api.PodList) ([]byte, error) { func gzipList(list *api.PodList) ([]byte, error) {
raw, err := v1.Codec.Encode(list) raw, err := runtime.Encode(api.Codecs.LegacyCodec(v1.SchemeGroupVersion), list)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -68,7 +69,7 @@ func gunzipList(gzipped []byte) (*api.PodList, error) { ...@@ -68,7 +69,7 @@ func gunzipList(gzipped []byte) (*api.PodList, error) {
return nil, err return nil, err
} }
obj, err := api.Scheme.Decode(raw) obj, err := runtime.Decode(api.Codecs.UniversalDecoder(), raw)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -27,6 +27,7 @@ import ( ...@@ -27,6 +27,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/runtime"
utilyaml "k8s.io/kubernetes/pkg/util/yaml" utilyaml "k8s.io/kubernetes/pkg/util/yaml"
) )
...@@ -41,7 +42,7 @@ func WriteToDir(pods <-chan *api.Pod, destDir string) error { ...@@ -41,7 +42,7 @@ func WriteToDir(pods <-chan *api.Pod, destDir string) error {
log.Warningf("skipping static pod %s/%s that had no filename", p.Namespace, p.Name) log.Warningf("skipping static pod %s/%s that had no filename", p.Namespace, p.Name)
continue continue
} }
raw, err := v1.Codec.Encode(p) raw, err := runtime.Encode(api.Codecs.LegacyCodec(v1.SchemeGroupVersion), p)
if err != nil { if err != nil {
log.Errorf("failed to encode static pod as v1 object: %v", err) log.Errorf("failed to encode static pod as v1 object: %v", err)
continue continue
...@@ -105,7 +106,7 @@ func tryDecodeSinglePod(data []byte) (parsed bool, pod *api.Pod, err error) { ...@@ -105,7 +106,7 @@ func tryDecodeSinglePod(data []byte) (parsed bool, pod *api.Pod, err error) {
if err != nil { if err != nil {
return false, nil, err return false, nil, err
} }
obj, err := api.Scheme.Decode(json) obj, err := runtime.Decode(api.Codecs.UniversalDecoder(), json)
if err != nil { if err != nil {
return false, pod, err return false, pod, err
} }
......
...@@ -26,6 +26,8 @@ import ( ...@@ -26,6 +26,8 @@ import (
annotation "k8s.io/kubernetes/contrib/mesos/pkg/scheduler/meta" annotation "k8s.io/kubernetes/contrib/mesos/pkg/scheduler/meta"
"k8s.io/kubernetes/contrib/mesos/pkg/scheduler/podtask" "k8s.io/kubernetes/contrib/mesos/pkg/scheduler/podtask"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime"
) )
type Binder interface { type Binder interface {
...@@ -150,7 +152,7 @@ func (b *binder) prepareTaskForLaunch(ctx api.Context, machine string, task *pod ...@@ -150,7 +152,7 @@ func (b *binder) prepareTaskForLaunch(ctx api.Context, machine string, task *pod
// the kubelet-executor uses this to instantiate the pod // the kubelet-executor uses this to instantiate the pod
log.V(3).Infof("prepared pod spec: %+v", pod) log.V(3).Infof("prepared pod spec: %+v", pod)
data, err := api.Codec.Encode(&pod) data, err := runtime.Encode(api.Codecs.LegacyCodec(v1.SchemeGroupVersion), &pod)
if err != nil { if err != nil {
log.V(2).Infof("Failed to marshal the pod spec: %v", err) log.V(2).Infof("Failed to marshal the pod spec: %v", err)
return err return err
......
...@@ -406,6 +406,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -406,6 +406,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -416,6 +419,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -416,6 +419,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -553,6 +559,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -553,6 +559,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -690,6 +699,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -690,6 +699,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -827,6 +839,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -827,6 +839,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -964,6 +979,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -964,6 +979,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -1109,6 +1127,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -1109,6 +1127,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -1254,6 +1275,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -1254,6 +1275,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -1367,6 +1391,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -1367,6 +1391,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -1496,6 +1523,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -1496,6 +1523,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -1617,6 +1647,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -1617,6 +1647,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -1738,6 +1771,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -1738,6 +1771,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -1865,6 +1901,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -1865,6 +1901,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -2010,6 +2049,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -2010,6 +2049,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -2155,6 +2197,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -2155,6 +2197,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -2268,6 +2313,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -2268,6 +2313,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -2397,6 +2445,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -2397,6 +2445,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -2518,6 +2569,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -2518,6 +2569,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -2639,6 +2693,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -2639,6 +2693,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -2766,6 +2823,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -2766,6 +2823,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -2887,6 +2947,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -2887,6 +2947,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -3032,6 +3095,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -3032,6 +3095,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -3177,6 +3243,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -3177,6 +3243,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -3290,6 +3359,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -3290,6 +3359,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -3419,6 +3491,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -3419,6 +3491,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -3540,6 +3615,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -3540,6 +3615,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -3661,6 +3739,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -3661,6 +3739,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -3788,6 +3869,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -3788,6 +3869,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -3909,6 +3993,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -3909,6 +3993,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -4054,6 +4141,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -4054,6 +4141,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -4199,6 +4289,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -4199,6 +4289,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -4312,6 +4405,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -4312,6 +4405,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -4441,6 +4537,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -4441,6 +4537,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -4562,6 +4661,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -4562,6 +4661,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -4683,6 +4785,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -4683,6 +4785,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -4810,6 +4915,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -4810,6 +4915,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -4931,6 +5039,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -4931,6 +5039,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -5044,6 +5155,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -5044,6 +5155,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -5165,6 +5279,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -5165,6 +5279,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -5292,6 +5409,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -5292,6 +5409,9 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li> <li>
<p>application/json</p> <p>application/json</p>
</li> </li>
<li>
<p>application/yaml</p>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -7051,7 +7171,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; } ...@@ -7051,7 +7171,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2016-01-06 14:06:54 UTC Last updated 2016-01-18 05:12:46 UTC
</div> </div>
</div> </div>
</body> </body>
......
...@@ -421,7 +421,7 @@ func TestExampleObjectSchemas(t *testing.T) { ...@@ -421,7 +421,7 @@ func TestExampleObjectSchemas(t *testing.T) {
return return
} }
if strings.Contains(name, "scheduler-policy-config") { if strings.Contains(name, "scheduler-policy-config") {
if err := schedulerapilatest.Codec.DecodeInto(data, expectedType); err != nil { if err := runtime.DecodeInto(schedulerapilatest.Codec, data, expectedType); err != nil {
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data)) t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data))
return return
} }
...@@ -516,14 +516,14 @@ func TestReadme(t *testing.T) { ...@@ -516,14 +516,14 @@ func TestReadme(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("%s could not be converted to JSON: %v\n%s", path, err, string(content)) t.Errorf("%s could not be converted to JSON: %v\n%s", path, err, string(content))
} }
if err := testapi.Default.Codec().DecodeInto(json, expectedType); err != nil { if err := runtime.DecodeInto(testapi.Default.Codec(), json, expectedType); err != nil {
t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(content)) t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(content))
continue continue
} }
if errors := validateObject(expectedType); len(errors) > 0 { if errors := validateObject(expectedType); len(errors) > 0 {
t.Errorf("%s did not validate correctly: %v", path, errors) t.Errorf("%s did not validate correctly: %v", path, errors)
} }
_, err = testapi.Default.Codec().Encode(expectedType) _, err = runtime.Encode(testapi.Default.Codec(), expectedType)
if err != nil { if err != nil {
t.Errorf("Could not encode object: %v", err) t.Errorf("Could not encode object: %v", err)
continue continue
......
...@@ -66,5 +66,5 @@ func main() { ...@@ -66,5 +66,5 @@ func main() {
"nginx.key": nginxKey, "nginx.key": nginxKey,
}, },
} }
fmt.Printf(runtime.EncodeOrDie(registered.GroupOrDie(api.GroupName).Codec, secret)) fmt.Printf(runtime.EncodeOrDie(api.Codecs.LegacyCodec(registered.EnabledVersions()...), secret))
} }
...@@ -59,5 +59,5 @@ func main() { ...@@ -59,5 +59,5 @@ func main() {
"config": cfg, "config": cfg,
}, },
} }
fmt.Printf(runtime.EncodeOrDie(registered.GroupOrDie(api.GroupName).Codec, secret)) fmt.Printf(runtime.EncodeOrDie(api.Codecs.LegacyCodec(registered.EnabledVersions()...), secret))
} }
...@@ -54,7 +54,7 @@ function generate_deep_copies() { ...@@ -54,7 +54,7 @@ function generate_deep_copies() {
else else
apiVersions="${ver}" apiVersions="${ver}"
fi fi
KUBE_API_VERSIONS="${apiVersions}" generate_version "${ver}" KUBE_API_VERSIONS="${apiVersions:-}" generate_version "${ver}"
done done
} }
...@@ -62,6 +62,6 @@ function generate_deep_copies() { ...@@ -62,6 +62,6 @@ function generate_deep_copies() {
# Currently pkg/api/deep_copy_generated.go is generated by the new go2idl generator. # Currently pkg/api/deep_copy_generated.go is generated by the new go2idl generator.
# All others (mentioned above) are still generated by the old reflection-based generator. # All others (mentioned above) are still generated by the old reflection-based generator.
# TODO: Migrate these to the new generator. # TODO: Migrate these to the new generator.
DEFAULT_VERSIONS="v1 authorization/ authorization/v1beta1 extensions/ extensions/v1beta1 componentconfig/ componentconfig/v1alpha1 metrics/ metrics/v1alpha1" DEFAULT_VERSIONS="v1 authorization/__internal authorization/v1beta1 extensions/__internal extensions/v1beta1 componentconfig/__internal componentconfig/v1alpha1 metrics/__internal metrics/v1alpha1"
VERSIONS=${VERSIONS:-$DEFAULT_VERSIONS} VERSIONS=${VERSIONS:-$DEFAULT_VERSIONS}
generate_deep_copies "$VERSIONS" generate_deep_copies "$VERSIONS"
...@@ -282,7 +282,7 @@ kube::util::group-version-to-pkg-path() { ...@@ -282,7 +282,7 @@ kube::util::group-version-to-pkg-path() {
# moving the results to pkg/apis/api. # moving the results to pkg/apis/api.
case "${group_version}" in case "${group_version}" in
# both group and version are "", this occurs when we generate deep copies for internal objects of the legacy v1 API. # both group and version are "", this occurs when we generate deep copies for internal objects of the legacy v1 API.
/) __internal)
echo "api" echo "api"
;; ;;
v1) v1)
...@@ -292,7 +292,7 @@ kube::util::group-version-to-pkg-path() { ...@@ -292,7 +292,7 @@ kube::util::group-version-to-pkg-path() {
echo "api/unversioned" echo "api/unversioned"
;; ;;
*) *)
echo "apis/${group_version}" echo "apis/${group_version%__internal}"
;; ;;
esac esac
} }
......
...@@ -22,14 +22,9 @@ import ( ...@@ -22,14 +22,9 @@ import (
"k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/intstr" "k8s.io/kubernetes/pkg/util/intstr"
) )
// Codec is the identity codec for this package - it can only convert itself
// to itself.
var Codec = runtime.CodecFor(Scheme, unversioned.GroupVersion{})
func init() { func init() {
Scheme.AddDefaultingFuncs( Scheme.AddDefaultingFuncs(
func(obj *ListOptions) { func(obj *ListOptions) {
......
...@@ -22,6 +22,7 @@ import ( ...@@ -22,6 +22,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/runtime"
) )
func BenchmarkPodConversion(b *testing.B) { func BenchmarkPodConversion(b *testing.B) {
...@@ -30,7 +31,7 @@ func BenchmarkPodConversion(b *testing.B) { ...@@ -30,7 +31,7 @@ func BenchmarkPodConversion(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err) b.Fatalf("Unexpected error while reading file: %v", err)
} }
var pod api.Pod var pod api.Pod
if err := api.Scheme.DecodeInto(data, &pod); err != nil { if err := runtime.DecodeInto(testapi.Default.Codec(), data, &pod); err != nil {
b.Fatalf("Unexpected error decoding pod: %v", err) b.Fatalf("Unexpected error decoding pod: %v", err)
} }
...@@ -41,7 +42,7 @@ func BenchmarkPodConversion(b *testing.B) { ...@@ -41,7 +42,7 @@ func BenchmarkPodConversion(b *testing.B) {
if err != nil { if err != nil {
b.Fatalf("Conversion error: %v", err) b.Fatalf("Conversion error: %v", err)
} }
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersions[testapi.Default.GroupVersion().Group].String()) obj, err := scheme.ConvertToVersion(versionedObj, testapi.Default.InternalGroupVersion().String())
if err != nil { if err != nil {
b.Fatalf("Conversion error: %v", err) b.Fatalf("Conversion error: %v", err)
} }
...@@ -58,7 +59,7 @@ func BenchmarkNodeConversion(b *testing.B) { ...@@ -58,7 +59,7 @@ func BenchmarkNodeConversion(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err) b.Fatalf("Unexpected error while reading file: %v", err)
} }
var node api.Node var node api.Node
if err := api.Scheme.DecodeInto(data, &node); err != nil { if err := runtime.DecodeInto(testapi.Default.Codec(), data, &node); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err) b.Fatalf("Unexpected error decoding node: %v", err)
} }
...@@ -69,7 +70,7 @@ func BenchmarkNodeConversion(b *testing.B) { ...@@ -69,7 +70,7 @@ func BenchmarkNodeConversion(b *testing.B) {
if err != nil { if err != nil {
b.Fatalf("Conversion error: %v", err) b.Fatalf("Conversion error: %v", err)
} }
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersions[testapi.Default.GroupVersion().Group].String()) obj, err := scheme.ConvertToVersion(versionedObj, testapi.Default.InternalGroupVersion().String())
if err != nil { if err != nil {
b.Fatalf("Conversion error: %v", err) b.Fatalf("Conversion error: %v", err)
} }
...@@ -86,7 +87,7 @@ func BenchmarkReplicationControllerConversion(b *testing.B) { ...@@ -86,7 +87,7 @@ func BenchmarkReplicationControllerConversion(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err) b.Fatalf("Unexpected error while reading file: %v", err)
} }
var replicationController api.ReplicationController var replicationController api.ReplicationController
if err := api.Scheme.DecodeInto(data, &replicationController); err != nil { if err := runtime.DecodeInto(testapi.Default.Codec(), data, &replicationController); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err) b.Fatalf("Unexpected error decoding node: %v", err)
} }
...@@ -97,7 +98,7 @@ func BenchmarkReplicationControllerConversion(b *testing.B) { ...@@ -97,7 +98,7 @@ func BenchmarkReplicationControllerConversion(b *testing.B) {
if err != nil { if err != nil {
b.Fatalf("Conversion error: %v", err) b.Fatalf("Conversion error: %v", err)
} }
obj, err := scheme.ConvertToVersion(versionedObj, scheme.InternalVersions[testapi.Default.GroupVersion().Group].String()) obj, err := scheme.ConvertToVersion(versionedObj, testapi.Default.InternalGroupVersion().String())
if err != nil { if err != nil {
b.Fatalf("Conversion error: %v", err) b.Fatalf("Conversion error: %v", err)
} }
......
...@@ -54,7 +54,7 @@ func doDeepCopyTest(t *testing.T, kind unversioned.GroupVersionKind, f *fuzz.Fuz ...@@ -54,7 +54,7 @@ func doDeepCopyTest(t *testing.T, kind unversioned.GroupVersionKind, f *fuzz.Fuz
} }
if !reflect.DeepEqual(item, itemCopy) { if !reflect.DeepEqual(item, itemCopy) {
t.Errorf("\nexpected: %#v\n\ngot: %#v\n\ndiff: %v", item, itemCopy, util.ObjectDiff(item, itemCopy)) t.Errorf("\nexpected: %#v\n\ngot: %#v\n\ndiff: %v", item, itemCopy, util.ObjectGoPrintSideBySide(item, itemCopy))
} }
} }
......
...@@ -2778,6 +2778,11 @@ func deepCopy_runtime_RawExtension(in runtime.RawExtension, out *runtime.RawExte ...@@ -2778,6 +2778,11 @@ func deepCopy_runtime_RawExtension(in runtime.RawExtension, out *runtime.RawExte
} else { } else {
out.RawJSON = nil out.RawJSON = nil
} }
if newVal, err := c.DeepCopy(in.Object); err != nil {
return err
} else {
out.Object = newVal.(runtime.Object)
}
return nil return nil
} }
......
...@@ -21,6 +21,8 @@ import ( ...@@ -21,6 +21,8 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/runtime"
) )
func BenchmarkPodCopy(b *testing.B) { func BenchmarkPodCopy(b *testing.B) {
...@@ -29,7 +31,7 @@ func BenchmarkPodCopy(b *testing.B) { ...@@ -29,7 +31,7 @@ func BenchmarkPodCopy(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err) b.Fatalf("Unexpected error while reading file: %v", err)
} }
var pod api.Pod var pod api.Pod
if err := api.Scheme.DecodeInto(data, &pod); err != nil { if err := runtime.DecodeInto(testapi.Default.Codec(), data, &pod); err != nil {
b.Fatalf("Unexpected error decoding pod: %v", err) b.Fatalf("Unexpected error decoding pod: %v", err)
} }
...@@ -52,7 +54,7 @@ func BenchmarkNodeCopy(b *testing.B) { ...@@ -52,7 +54,7 @@ func BenchmarkNodeCopy(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err) b.Fatalf("Unexpected error while reading file: %v", err)
} }
var node api.Node var node api.Node
if err := api.Scheme.DecodeInto(data, &node); err != nil { if err := runtime.DecodeInto(testapi.Default.Codec(), data, &node); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err) b.Fatalf("Unexpected error decoding node: %v", err)
} }
...@@ -75,7 +77,7 @@ func BenchmarkReplicationControllerCopy(b *testing.B) { ...@@ -75,7 +77,7 @@ func BenchmarkReplicationControllerCopy(b *testing.B) {
b.Fatalf("Unexpected error while reading file: %v", err) b.Fatalf("Unexpected error while reading file: %v", err)
} }
var replicationController api.ReplicationController var replicationController api.ReplicationController
if err := api.Scheme.DecodeInto(data, &replicationController); err != nil { if err := runtime.DecodeInto(testapi.Default.Codec(), data, &replicationController); err != nil {
b.Fatalf("Unexpected error decoding node: %v", err) b.Fatalf("Unexpected error decoding node: %v", err)
} }
......
...@@ -24,14 +24,13 @@ import ( ...@@ -24,14 +24,13 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apimachinery"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apimachinery"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/sets"
) )
const importPrefix = "k8s.io/kubernetes/pkg/api" const importPrefix = "k8s.io/kubernetes/pkg/api"
...@@ -75,7 +74,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error { ...@@ -75,7 +74,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error {
groupMeta := apimachinery.GroupMeta{ groupMeta := apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion, GroupVersion: preferredExternalVersion,
GroupVersions: externalVersions, GroupVersions: externalVersions,
Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion),
RESTMapper: newRESTMapper(externalVersions), RESTMapper: newRESTMapper(externalVersions),
SelfLinker: runtime.SelfLinker(accessor), SelfLinker: runtime.SelfLinker(accessor),
InterfacesFor: interfacesFor, InterfacesFor: interfacesFor,
...@@ -127,7 +125,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e ...@@ -127,7 +125,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e
switch version { switch version {
case v1.SchemeGroupVersion: case v1.SchemeGroupVersion:
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
Codec: v1.Codec,
ObjectConvertor: api.Scheme, ObjectConvertor: api.Scheme,
MetadataAccessor: accessor, MetadataAccessor: accessor,
}, nil }, nil
......
...@@ -18,11 +18,13 @@ package install ...@@ -18,11 +18,13 @@ package install
import ( import (
"encoding/json" "encoding/json"
"reflect"
"testing" "testing"
internal "k8s.io/kubernetes/pkg/api" internal "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/runtime"
) )
func TestResourceVersioner(t *testing.T) { func TestResourceVersioner(t *testing.T) {
...@@ -49,7 +51,7 @@ func TestCodec(t *testing.T) { ...@@ -49,7 +51,7 @@ func TestCodec(t *testing.T) {
pod := internal.Pod{} pod := internal.Pod{}
// We do want to use package registered rather than testapi here, because we // We do want to use package registered rather than testapi here, because we
// want to test if the package install and package registered work as expected. // want to test if the package install and package registered work as expected.
data, err := registered.GroupOrDie(internal.GroupName).Codec.Encode(&pod) data, err := runtime.Encode(internal.Codecs.LegacyCodec(registered.GroupOrDie(internal.GroupName).GroupVersion), &pod)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
...@@ -100,8 +102,8 @@ func TestRESTMapper(t *testing.T) { ...@@ -100,8 +102,8 @@ func TestRESTMapper(t *testing.T) {
} }
interfaces, _ := registered.GroupOrDie(internal.GroupName).InterfacesFor(version) interfaces, _ := registered.GroupOrDie(internal.GroupName).InterfacesFor(version)
if mapping.Codec != interfaces.Codec { if mapping.ObjectConvertor != interfaces.ObjectConvertor {
t.Errorf("unexpected codec: %#v, expected: %#v", mapping, interfaces) t.Errorf("unexpected: %#v, expected: %#v", mapping, interfaces)
} }
rc := &internal.ReplicationController{ObjectMeta: internal.ObjectMeta{Name: "foo"}} rc := &internal.ReplicationController{ObjectMeta: internal.ObjectMeta{Name: "foo"}}
...@@ -114,3 +116,14 @@ func TestRESTMapper(t *testing.T) { ...@@ -114,3 +116,14 @@ func TestRESTMapper(t *testing.T) {
} }
} }
} }
func TestUnversioned(t *testing.T) {
for _, obj := range []runtime.Object{
&unversioned.Status{},
&unversioned.ExportOptions{},
} {
if unversioned, ok := internal.Scheme.IsUnversioned(obj); !unversioned || !ok {
t.Errorf("%v is expected to be unversioned", reflect.TypeOf(obj))
}
}
}
...@@ -120,7 +120,7 @@ func SetList(list runtime.Object, objects []runtime.Object) error { ...@@ -120,7 +120,7 @@ func SetList(list runtime.Object, objects []runtime.Object) error {
} else if src.Type().ConvertibleTo(dest.Type()) { } else if src.Type().ConvertibleTo(dest.Type()) {
dest.Set(src.Convert(dest.Type())) dest.Set(src.Convert(dest.Type()))
} else { } else {
return fmt.Errorf("item[%d]: Type mismatch: Expected %v, got %v", i, dest.Type(), src.Type()) return fmt.Errorf("item[%d]: can't assign or convert %v into %v", i, src.Type(), dest.Type())
} }
} }
items.Set(slice) items.Set(slice)
......
...@@ -24,7 +24,6 @@ import ( ...@@ -24,7 +24,6 @@ import (
// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version. // VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
type VersionInterfaces struct { type VersionInterfaces struct {
runtime.Codec
runtime.ObjectConvertor runtime.ObjectConvertor
MetadataAccessor MetadataAccessor
} }
...@@ -142,7 +141,6 @@ type RESTMapping struct { ...@@ -142,7 +141,6 @@ type RESTMapping struct {
// Scope contains the information needed to deal with REST Resources that are in a resource hierarchy // Scope contains the information needed to deal with REST Resources that are in a resource hierarchy
Scope RESTScope Scope RESTScope
runtime.Codec
runtime.ObjectConvertor runtime.ObjectConvertor
MetadataAccessor MetadataAccessor
} }
......
...@@ -73,7 +73,7 @@ func TestAPIObjectMeta(t *testing.T) { ...@@ -73,7 +73,7 @@ func TestAPIObjectMeta(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
if e, a := "/a", typeAccessor.GetAPIVersion(); e != a { if e, a := "a", typeAccessor.GetAPIVersion(); e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "b", typeAccessor.GetKind(); e != a { if e, a := "b", typeAccessor.GetKind(); e != a {
...@@ -102,7 +102,7 @@ func TestAPIObjectMeta(t *testing.T) { ...@@ -102,7 +102,7 @@ func TestAPIObjectMeta(t *testing.T) {
if e, a := types.UID("other"), j.UID; e != a { if e, a := types.UID("other"), j.UID; e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "/c", j.APIVersion; e != a { if e, a := "c", j.APIVersion; e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "d", j.Kind; e != a { if e, a := "d", j.Kind; e != a {
...@@ -117,7 +117,7 @@ func TestAPIObjectMeta(t *testing.T) { ...@@ -117,7 +117,7 @@ func TestAPIObjectMeta(t *testing.T) {
typeAccessor.SetAPIVersion("d") typeAccessor.SetAPIVersion("d")
typeAccessor.SetKind("e") typeAccessor.SetKind("e")
if e, a := "/d", j.APIVersion; e != a { if e, a := "d", j.APIVersion; e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "e", j.Kind; e != a { if e, a := "e", j.Kind; e != a {
...@@ -308,7 +308,7 @@ func TestGenericTypeMetaAccessor(t *testing.T) { ...@@ -308,7 +308,7 @@ func TestGenericTypeMetaAccessor(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if e, a := "/a", apiVersion; e != a { if e, a := "a", apiVersion; e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
kind, err := accessor.Kind(j) kind, err := accessor.Kind(j)
...@@ -392,7 +392,7 @@ func TestGenericTypeMetaAccessor(t *testing.T) { ...@@ -392,7 +392,7 @@ func TestGenericTypeMetaAccessor(t *testing.T) {
if e, a := "other", j.TypeMeta.UID; e != a { if e, a := "other", j.TypeMeta.UID; e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "/c", j.TypeMeta.APIVersion; e != a { if e, a := "c", j.TypeMeta.APIVersion; e != a {
t.Errorf("expected %v, got %v", e, a) t.Errorf("expected %v, got %v", e, a)
} }
if e, a := "d", j.TypeMeta.Kind; e != a { if e, a := "d", j.TypeMeta.Kind; e != a {
...@@ -757,7 +757,7 @@ func BenchmarkAccessorSetReflection(b *testing.B) { ...@@ -757,7 +757,7 @@ func BenchmarkAccessorSetReflection(b *testing.B) {
Name: "foo", Name: "foo",
GenerateName: "prefix", GenerateName: "prefix",
UID: "uid", UID: "uid",
APIVersion: "/a", APIVersion: "a",
Kind: "b", Kind: "b",
ResourceVersion: "1", ResourceVersion: "1",
SelfLink: "some/place/only/we/know", SelfLink: "some/place/only/we/know",
......
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"strings" "strings"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/sets"
) )
...@@ -84,7 +85,7 @@ type DefaultRESTMapper struct { ...@@ -84,7 +85,7 @@ type DefaultRESTMapper struct {
var _ RESTMapper = &DefaultRESTMapper{} var _ RESTMapper = &DefaultRESTMapper{}
// VersionInterfacesFunc returns the appropriate codec, typer, and metadata accessor for a // VersionInterfacesFunc returns the appropriate typer, and metadata accessor for a
// given api version, or an error if no such api version exists. // given api version, or an error if no such api version exists.
type VersionInterfacesFunc func(version unversioned.GroupVersion) (*VersionInterfaces, error) type VersionInterfacesFunc func(version unversioned.GroupVersion) (*VersionInterfaces, error)
...@@ -92,7 +93,7 @@ type VersionInterfacesFunc func(version unversioned.GroupVersion) (*VersionInter ...@@ -92,7 +93,7 @@ type VersionInterfacesFunc func(version unversioned.GroupVersion) (*VersionInter
// to a resource name and back based on the objects in a runtime.Scheme // to a resource name and back based on the objects in a runtime.Scheme
// and the Kubernetes API conventions. Takes a group name, a priority list of the versions // and the Kubernetes API conventions. Takes a group name, a priority list of the versions
// to search when an object has no default version (set empty to return an error), // to search when an object has no default version (set empty to return an error),
// and a function that retrieves the correct codec and metadata for a given version. // and a function that retrieves the correct metadata for a given version.
func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, f VersionInterfacesFunc) *DefaultRESTMapper { func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, f VersionInterfacesFunc) *DefaultRESTMapper {
resourceToKind := make(map[unversioned.GroupVersionResource]unversioned.GroupVersionKind) resourceToKind := make(map[unversioned.GroupVersionResource]unversioned.GroupVersionKind)
kindToPluralResource := make(map[unversioned.GroupVersionKind]unversioned.GroupVersionResource) kindToPluralResource := make(map[unversioned.GroupVersionKind]unversioned.GroupVersionResource)
...@@ -251,6 +252,9 @@ func (m *DefaultRESTMapper) ResourceFor(resource unversioned.GroupVersionResourc ...@@ -251,6 +252,9 @@ func (m *DefaultRESTMapper) ResourceFor(resource unversioned.GroupVersionResourc
func (m *DefaultRESTMapper) KindsFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error) { func (m *DefaultRESTMapper) KindsFor(input unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error) {
resource := input.GroupVersion().WithResource(strings.ToLower(input.Resource)) resource := input.GroupVersion().WithResource(strings.ToLower(input.Resource))
if resource.Version == runtime.APIVersionInternal {
resource.Version = ""
}
hasResource := len(resource.Resource) > 0 hasResource := len(resource.Resource) > 0
hasGroup := len(resource.Group) > 0 hasGroup := len(resource.Group) > 0
...@@ -412,7 +416,7 @@ func (m *DefaultRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...st ...@@ -412,7 +416,7 @@ func (m *DefaultRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...st
var gvk *unversioned.GroupVersionKind var gvk *unversioned.GroupVersionKind
hadVersion := false hadVersion := false
for _, version := range versions { for _, version := range versions {
if len(version) == 0 { if len(version) == 0 || version == runtime.APIVersionInternal {
continue continue
} }
...@@ -472,7 +476,6 @@ func (m *DefaultRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...st ...@@ -472,7 +476,6 @@ func (m *DefaultRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...st
GroupVersionKind: *gvk, GroupVersionKind: *gvk,
Scope: scope, Scope: scope,
Codec: interfaces.Codec,
ObjectConvertor: interfaces.ObjectConvertor, ObjectConvertor: interfaces.ObjectConvertor,
MetadataAccessor: interfaces.MetadataAccessor, MetadataAccessor: interfaces.MetadataAccessor,
} }
......
...@@ -18,8 +18,6 @@ package meta ...@@ -18,8 +18,6 @@ package meta
import ( import (
"errors" "errors"
"io"
"net/url"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
...@@ -28,38 +26,6 @@ import ( ...@@ -28,38 +26,6 @@ import (
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
type fakeCodec struct{}
var _ runtime.Decoder = fakeCodec{}
func (fakeCodec) Encode(runtime.Object) ([]byte, error) {
return []byte{}, nil
}
func (fakeCodec) EncodeToStream(runtime.Object, io.Writer) error {
return nil
}
func (fakeCodec) Decode([]byte) (runtime.Object, error) {
return nil, nil
}
func (fakeCodec) DecodeToVersion([]byte, unversioned.GroupVersion) (runtime.Object, error) {
return nil, nil
}
func (fakeCodec) DecodeInto([]byte, runtime.Object) error {
return nil
}
func (fakeCodec) DecodeIntoWithSpecifiedVersionKind([]byte, runtime.Object, unversioned.GroupVersionKind) error {
return nil
}
func (fakeCodec) DecodeParametersInto(parameters url.Values, obj runtime.Object) error {
return nil
}
type fakeConvertor struct{} type fakeConvertor struct{}
func (fakeConvertor) Convert(in, out interface{}) error { func (fakeConvertor) Convert(in, out interface{}) error {
...@@ -74,12 +40,11 @@ func (fakeConvertor) ConvertFieldLabel(version, kind, label, value string) (stri ...@@ -74,12 +40,11 @@ func (fakeConvertor) ConvertFieldLabel(version, kind, label, value string) (stri
return label, value, nil return label, value, nil
} }
var validCodec = fakeCodec{}
var validAccessor = resourceAccessor{} var validAccessor = resourceAccessor{}
var validConvertor = fakeConvertor{} var validConvertor = fakeConvertor{}
func fakeInterfaces(version unversioned.GroupVersion) (*VersionInterfaces, error) { func fakeInterfaces(version unversioned.GroupVersion) (*VersionInterfaces, error) {
return &VersionInterfaces{Codec: validCodec, ObjectConvertor: validConvertor, MetadataAccessor: validAccessor}, nil return &VersionInterfaces{ObjectConvertor: validConvertor, MetadataAccessor: validAccessor}, nil
} }
var unmatchedErr = errors.New("no version") var unmatchedErr = errors.New("no version")
...@@ -512,7 +477,7 @@ func TestRESTMapperRESTMapping(t *testing.T) { ...@@ -512,7 +477,7 @@ func TestRESTMapperRESTMapping(t *testing.T) {
t.Errorf("%d: unexpected resource: %#v", i, mapping) t.Errorf("%d: unexpected resource: %#v", i, mapping)
} }
if mapping.Codec == nil || mapping.MetadataAccessor == nil || mapping.ObjectConvertor == nil { if mapping.MetadataAccessor == nil || mapping.ObjectConvertor == nil {
t.Errorf("%d: missing codec and accessor: %#v", i, mapping) t.Errorf("%d: missing codec and accessor: %#v", i, mapping)
} }
......
...@@ -20,16 +20,27 @@ import ( ...@@ -20,16 +20,27 @@ import (
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime/serializer"
) )
// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered. // Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered.
var Scheme = runtime.NewScheme() var Scheme = runtime.NewScheme()
// Codecs provides access to encoding and decoding for the scheme
var Codecs = serializer.NewCodecFactory(Scheme)
// GroupName is the group name use in this package // GroupName is the group name use in this package
const GroupName = "" const GroupName = ""
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: ""} var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Unversiond is group version for unversioned API objects
// TODO: this should be v1 probably
var Unversioned = unversioned.GroupVersion{Group: "", Version: "v1"}
// ParameterCodec handles versioning of objects that are converted to query parameters.
var ParameterCodec = runtime.NewParameterCodec(Scheme)
// Kind takes an unqualified kind and returns back a Group qualified GroupKind // Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind { func Kind(kind string) unversioned.GroupKind {
...@@ -42,6 +53,9 @@ func Resource(resource string) unversioned.GroupResource { ...@@ -42,6 +53,9 @@ func Resource(resource string) unversioned.GroupResource {
} }
func AddToScheme(scheme *runtime.Scheme) { func AddToScheme(scheme *runtime.Scheme) {
if err := Scheme.AddIgnoredConversionType(&unversioned.TypeMeta{}, &unversioned.TypeMeta{}); err != nil {
panic(err)
}
scheme.AddKnownTypes(SchemeGroupVersion, scheme.AddKnownTypes(SchemeGroupVersion,
&Pod{}, &Pod{},
&PodList{}, &PodList{},
...@@ -86,14 +100,15 @@ func AddToScheme(scheme *runtime.Scheme) { ...@@ -86,14 +100,15 @@ func AddToScheme(scheme *runtime.Scheme) {
&RangeAllocation{}, &RangeAllocation{},
) )
// Add the Unversioned types to scheme. // Register Unversioned types under their own special group
// TODO this should not be done here Scheme.AddUnversionedTypes(Unversioned,
scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.ExportOptions{}) &unversioned.ExportOptions{},
scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.Status{}) &unversioned.Status{},
scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.APIVersions{}) &unversioned.APIVersions{},
scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.APIGroupList{}) &unversioned.APIGroupList{},
scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.APIGroup{}) &unversioned.APIGroup{},
scheme.AddKnownTypes(SchemeGroupVersion, &unversioned.APIResourceList{}) &unversioned.APIResourceList{},
)
} }
func (obj *Pod) GetObjectMeta() meta.Object { return &obj.ObjectMeta } func (obj *Pod) GetObjectMeta() meta.Object { return &obj.ObjectMeta }
......
...@@ -61,6 +61,8 @@ func fuzzInternalObject(t *testing.T, forVersion unversioned.GroupVersion, item ...@@ -61,6 +61,8 @@ func fuzzInternalObject(t *testing.T, forVersion unversioned.GroupVersion, item
} }
func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) { func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) {
t.Logf("codec: %#v", codec)
printer := spew.ConfigState{DisableMethods: true} printer := spew.ConfigState{DisableMethods: true}
name := reflect.TypeOf(item).Elem().Name() name := reflect.TypeOf(item).Elem().Name()
...@@ -81,8 +83,7 @@ func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) { ...@@ -81,8 +83,7 @@ func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) {
} }
obj3 := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) obj3 := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object)
err = runtime.DecodeInto(codec, data, obj3) if err := runtime.DecodeInto(codec, data, obj3); err != nil {
if err != nil {
t.Errorf("2: %v: %v", name, err) t.Errorf("2: %v: %v", name, err)
return return
} }
...@@ -122,7 +123,7 @@ func TestSpecificKind(t *testing.T) { ...@@ -122,7 +123,7 @@ func TestSpecificKind(t *testing.T) {
// api.Scheme.Log(t) // api.Scheme.Log(t)
// defer api.Scheme.Log(nil) // defer api.Scheme.Log(nil)
kind := "Pod" kind := "List"
for i := 0; i < *fuzzIters; i++ { for i := 0; i < *fuzzIters; i++ {
doRoundTripTest(kind, t) doRoundTripTest(kind, t)
if t.Failed() { if t.Failed() {
...@@ -180,7 +181,7 @@ func doRoundTripTest(kind string, t *testing.T) { ...@@ -180,7 +181,7 @@ func doRoundTripTest(kind string, t *testing.T) {
roundTripSame(t, item, nonRoundTrippableTypesByVersion[kind]...) roundTripSame(t, item, nonRoundTrippableTypesByVersion[kind]...)
} }
if !nonInternalRoundTrippableTypes.Has(kind) { if !nonInternalRoundTrippableTypes.Has(kind) {
roundTrip(t, api.Codec, fuzzInternalObject(t, testapi.Default.InternalGroupVersion(), item, rand.Int63())) roundTrip(t, testapi.Default.Codec(), fuzzInternalObject(t, testapi.Default.InternalGroupVersion(), item, rand.Int63()))
} }
} }
...@@ -200,8 +201,8 @@ func TestEncode_Ptr(t *testing.T) { ...@@ -200,8 +201,8 @@ func TestEncode_Ptr(t *testing.T) {
}, },
} }
obj := runtime.Object(pod) obj := runtime.Object(pod)
data, err := testapi.Default.Codec().Encode(obj) data, err := runtime.Encode(testapi.Default.Codec(), obj)
obj2, err2 := testapi.Default.Codec().Decode(data) obj2, err2 := runtime.Decode(testapi.Default.Codec(), data)
if err != nil || err2 != nil { if err != nil || err2 != nil {
t.Fatalf("Failure: '%v' '%v'", err, err2) t.Fatalf("Failure: '%v' '%v'", err, err2)
} }
...@@ -216,11 +217,11 @@ func TestEncode_Ptr(t *testing.T) { ...@@ -216,11 +217,11 @@ func TestEncode_Ptr(t *testing.T) {
func TestBadJSONRejection(t *testing.T) { func TestBadJSONRejection(t *testing.T) {
badJSONMissingKind := []byte(`{ }`) badJSONMissingKind := []byte(`{ }`)
if _, err := testapi.Default.Codec().Decode(badJSONMissingKind); err == nil { if _, err := runtime.Decode(testapi.Default.Codec(), badJSONMissingKind); err == nil {
t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind) t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
} }
badJSONUnknownType := []byte(`{"kind": "bar"}`) badJSONUnknownType := []byte(`{"kind": "bar"}`)
if _, err1 := testapi.Default.Codec().Decode(badJSONUnknownType); err1 == nil { if _, err1 := runtime.Decode(testapi.Default.Codec(), badJSONUnknownType); err1 == nil {
t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType) t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
} }
/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`) /*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
...@@ -240,14 +241,14 @@ func TestUnversionedTypes(t *testing.T) { ...@@ -240,14 +241,14 @@ func TestUnversionedTypes(t *testing.T) {
for _, obj := range testcases { for _, obj := range testcases {
// Make sure the unversioned codec can encode // Make sure the unversioned codec can encode
unversionedJSON, err := api.Codec.Encode(obj) unversionedJSON, err := runtime.Encode(testapi.Default.Codec(), obj)
if err != nil { if err != nil {
t.Errorf("%v: unexpected error: %v", obj, err) t.Errorf("%v: unexpected error: %v", obj, err)
continue continue
} }
// Make sure the versioned codec under test can decode // Make sure the versioned codec under test can decode
versionDecodedObject, err := testapi.Default.Codec().Decode(unversionedJSON) versionDecodedObject, err := runtime.Decode(testapi.Default.Codec(), unversionedJSON)
if err != nil { if err != nil {
t.Errorf("%v: unexpected error: %v", obj, err) t.Errorf("%v: unexpected error: %v", obj, err)
continue continue
...@@ -278,7 +279,7 @@ func BenchmarkEncodeCodec(b *testing.B) { ...@@ -278,7 +279,7 @@ func BenchmarkEncodeCodec(b *testing.B) {
width := len(items) width := len(items)
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
if _, err := testapi.Default.Codec().Encode(&items[i%width]); err != nil { if _, err := runtime.Encode(testapi.Default.Codec(), &items[i%width]); err != nil {
b.Fatal(err) b.Fatal(err)
} }
} }
...@@ -320,7 +321,7 @@ func BenchmarkDecodeCodec(b *testing.B) { ...@@ -320,7 +321,7 @@ func BenchmarkDecodeCodec(b *testing.B) {
b.StopTimer() b.StopTimer()
} }
func BenchmarkDecodeIntoCodec(b *testing.B) { func BenchmarkDecodeIntoExternalCodec(b *testing.B) {
codec := testapi.Default.Codec() codec := testapi.Default.Codec()
items := benchmarkItems() items := benchmarkItems()
width := len(items) width := len(items)
...@@ -343,6 +344,29 @@ func BenchmarkDecodeIntoCodec(b *testing.B) { ...@@ -343,6 +344,29 @@ func BenchmarkDecodeIntoCodec(b *testing.B) {
b.StopTimer() b.StopTimer()
} }
func BenchmarkDecodeIntoInternalCodec(b *testing.B) {
codec := testapi.Default.Codec()
items := benchmarkItems()
width := len(items)
encoded := make([][]byte, width)
for i := range items {
data, err := runtime.Encode(codec, &items[i])
if err != nil {
b.Fatal(err)
}
encoded[i] = data
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
obj := api.Pod{}
if err := runtime.DecodeInto(codec, encoded[i%width], &obj); err != nil {
b.Fatal(err)
}
}
b.StopTimer()
}
// BenchmarkDecodeJSON provides a baseline for regular JSON decode performance // BenchmarkDecodeJSON provides a baseline for regular JSON decode performance
func BenchmarkDecodeIntoJSON(b *testing.B) { func BenchmarkDecodeIntoJSON(b *testing.B) {
codec := testapi.Default.Codec() codec := testapi.Default.Codec()
......
...@@ -47,7 +47,7 @@ type TestGroup struct { ...@@ -47,7 +47,7 @@ type TestGroup struct {
func init() { func init() {
kubeTestAPI := os.Getenv("KUBE_TEST_API") kubeTestAPI := os.Getenv("KUBE_TEST_API")
if kubeTestAPI != "" { if len(kubeTestAPI) != 0 {
testGroupVersions := strings.Split(kubeTestAPI, ",") testGroupVersions := strings.Split(kubeTestAPI, ",")
for _, gvString := range testGroupVersions { for _, gvString := range testGroupVersions {
groupVersion, err := unversioned.ParseGroupVersion(gvString) groupVersion, err := unversioned.ParseGroupVersion(gvString)
...@@ -57,7 +57,7 @@ func init() { ...@@ -57,7 +57,7 @@ func init() {
Groups[groupVersion.Group] = TestGroup{ Groups[groupVersion.Group] = TestGroup{
externalGroupVersion: groupVersion, externalGroupVersion: groupVersion,
internalGroupVersion: unversioned.GroupVersion{Group: groupVersion.Group}, internalGroupVersion: unversioned.GroupVersion{Group: groupVersion.Group, Version: runtime.APIVersionInternal},
} }
} }
} }
...@@ -93,12 +93,7 @@ func (g TestGroup) InternalGroupVersion() unversioned.GroupVersion { ...@@ -93,12 +93,7 @@ func (g TestGroup) InternalGroupVersion() unversioned.GroupVersion {
// Codec returns the codec for the API version to test against, as set by the // Codec returns the codec for the API version to test against, as set by the
// KUBE_TEST_API env var. // KUBE_TEST_API env var.
func (g TestGroup) Codec() runtime.Codec { func (g TestGroup) Codec() runtime.Codec {
// TODO: caesarxuchao: Restructure the body once we have a central `registered`. return api.Codecs.LegacyCodec(g.externalGroupVersion)
interfaces, err := registered.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion)
if err != nil {
panic(err)
}
return interfaces.Codec
} }
// Converter returns the api.Scheme for the API version to test against, as set by the // Converter returns the api.Scheme for the API version to test against, as set by the
...@@ -199,7 +194,11 @@ func GetCodecForObject(obj runtime.Object) (runtime.Codec, error) { ...@@ -199,7 +194,11 @@ func GetCodecForObject(obj runtime.Object) (runtime.Codec, error) {
} }
// Codec used for unversioned types // Codec used for unversioned types
if api.Scheme.Recognizes(kind) { if api.Scheme.Recognizes(kind) {
return api.Codec, nil serializer, ok := api.Codecs.SerializerForFileExtension("json")
if !ok {
return nil, fmt.Errorf("no serializer registered for json")
}
return serializer, nil
} }
return nil, fmt.Errorf("unexpected kind: %v", kind) return nil, fmt.Errorf("unexpected kind: %v", kind)
} }
......
...@@ -17,7 +17,12 @@ limitations under the License. ...@@ -17,7 +17,12 @@ limitations under the License.
package testapi package testapi
import ( import (
"encoding/json"
"reflect"
"testing" "testing"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
) )
// TODO these tests don't add much value for testing things that have groups // TODO these tests don't add much value for testing things that have groups
...@@ -61,3 +66,61 @@ func TestResourcePath(t *testing.T) { ...@@ -61,3 +66,61 @@ func TestResourcePath(t *testing.T) {
} }
} }
} }
var status = &unversioned.Status{
Status: unversioned.StatusFailure,
Code: 200,
Reason: unversioned.StatusReasonUnknown,
Message: "",
}
func TestV1EncodeDecodeStatus(t *testing.T) {
v1Codec := Default.Codec()
encoded, err := runtime.Encode(v1Codec, status)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
typeMeta := unversioned.TypeMeta{}
if err := json.Unmarshal(encoded, &typeMeta); err != nil {
t.Errorf("unexpected error: %v", err)
}
if typeMeta.Kind != "Status" {
t.Errorf("Kind is not set to \"Status\". Got %v", string(encoded))
}
if typeMeta.APIVersion != "v1" {
t.Errorf("APIVersion is not set to \"v1\". Got %v", string(encoded))
}
decoded, err := runtime.Decode(v1Codec, encoded)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !reflect.DeepEqual(status, decoded) {
t.Errorf("expected: %#v, got: %#v", status, decoded)
}
}
func TestExperimentalEncodeDecodeStatus(t *testing.T) {
extensionCodec := Extensions.Codec()
encoded, err := runtime.Encode(extensionCodec, status)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
typeMeta := unversioned.TypeMeta{}
if err := json.Unmarshal(encoded, &typeMeta); err != nil {
t.Errorf("unexpected error: %v", err)
}
if typeMeta.Kind != "Status" {
t.Errorf("Kind is not set to \"Status\". Got %s", encoded)
}
if typeMeta.APIVersion != "v1" {
t.Errorf("APIVersion is not set to \"\". Got %s", encoded)
}
decoded, err := runtime.Decode(extensionCodec, encoded)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !reflect.DeepEqual(status, decoded) {
t.Errorf("expected: %v, got: %v", status, decoded)
}
}
...@@ -48,7 +48,7 @@ func TestCompatibility( ...@@ -48,7 +48,7 @@ func TestCompatibility(
) { ) {
// Decode // Decode
codec := runtime.CodecFor(api.Scheme, version) codec := api.Codecs.LegacyCodec(version)
obj, err := runtime.Decode(codec, input) obj, err := runtime.Decode(codec, input)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
......
...@@ -59,9 +59,6 @@ func FuzzerFor(t *testing.T, version unversioned.GroupVersion, src rand.Source) ...@@ -59,9 +59,6 @@ func FuzzerFor(t *testing.T, version unversioned.GroupVersion, src rand.Source)
func(q *resource.Quantity, c fuzz.Continue) { func(q *resource.Quantity, c fuzz.Continue) {
*q = *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent) *q = *resource.NewQuantity(c.Int63n(1000), resource.DecimalExponent)
}, },
func(j *runtime.PluginBase, c fuzz.Continue) {
// Do nothing; this struct has only a Kind field and it must stay blank in memory.
},
func(j *runtime.TypeMeta, c fuzz.Continue) { func(j *runtime.TypeMeta, c fuzz.Continue) {
// We have to customize the randomization of TypeMetas because their // We have to customize the randomization of TypeMetas because their
// APIVersion and Kind must remain blank in memory. // APIVersion and Kind must remain blank in memory.
...@@ -177,10 +174,8 @@ func FuzzerFor(t *testing.T, version unversioned.GroupVersion, src rand.Source) ...@@ -177,10 +174,8 @@ func FuzzerFor(t *testing.T, version unversioned.GroupVersion, src rand.Source)
// TODO: uncomment when round trip starts from a versioned object // TODO: uncomment when round trip starts from a versioned object
if true { //c.RandBool() { if true { //c.RandBool() {
*j = &runtime.Unknown{ *j = &runtime.Unknown{
// apiVersion has rules now. Since it includes <group>/<version> and only `v1` can be bare, // We do not set TypeMeta here because it is not carried through a round trip
// then this must choose a valid format to deserialize RawJSON: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`),
TypeMeta: runtime.TypeMeta{Kind: "Something", APIVersion: "unknown.group/unknown"},
RawJSON: []byte(`{"apiVersion":"unknown.group/unknown","kind":"Something","someKey":"someValue"}`),
} }
} else { } else {
types := []runtime.Object{&api.Pod{}, &api.ReplicationController{}} types := []runtime.Object{&api.Pod{}, &api.ReplicationController{}}
......
...@@ -141,11 +141,13 @@ func (gv GroupVersion) String() string { ...@@ -141,11 +141,13 @@ func (gv GroupVersion) String() string {
} }
// special case of "v1" for backward compatibility // special case of "v1" for backward compatibility
if gv.Group == "" && gv.Version == "v1" { if len(gv.Group) == 0 && gv.Version == "v1" {
return gv.Version return gv.Version
} else { }
if len(gv.Group) > 0 {
return gv.Group + "/" + gv.Version return gv.Group + "/" + gv.Version
} }
return gv.Version
} }
// ParseGroupVersion turns "group/version" string into a GroupVersion struct. It reports error // ParseGroupVersion turns "group/version" string into a GroupVersion struct. It reports error
...@@ -163,6 +165,8 @@ func ParseGroupVersion(gv string) (GroupVersion, error) { ...@@ -163,6 +165,8 @@ func ParseGroupVersion(gv string) (GroupVersion, error) {
switch { switch {
case len(s) == 1 && gv == "v1": case len(s) == 1 && gv == "v1":
return GroupVersion{"", "v1"}, nil return GroupVersion{"", "v1"}, nil
case len(s) == 1:
return GroupVersion{"", s[0]}, nil
case len(s) == 2: case len(s) == 2:
return GroupVersion{s[0], s[1]}, nil return GroupVersion{s[0], s[1]}, nil
default: default:
......
...@@ -2471,6 +2471,13 @@ func deepCopy_runtime_RawExtension(in runtime.RawExtension, out *runtime.RawExte ...@@ -2471,6 +2471,13 @@ func deepCopy_runtime_RawExtension(in runtime.RawExtension, out *runtime.RawExte
} else { } else {
out.RawJSON = nil out.RawJSON = nil
} }
if newVal, err := c.DeepCopy(in.Object); err != nil {
return err
} else if newVal == nil {
out.Object = nil
} else {
out.Object = newVal.(runtime.Object)
}
return nil return nil
} }
......
...@@ -28,12 +28,13 @@ import ( ...@@ -28,12 +28,13 @@ import (
) )
func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
data, err := versioned.Codec.Encode(obj) codec := api.Codecs.LegacyCodec(versioned.SchemeGroupVersion)
data, err := runtime.Encode(codec, obj)
if err != nil { if err != nil {
t.Errorf("%v\n %#v", err, obj) t.Errorf("%v\n %#v", err, obj)
return nil return nil
} }
obj2, err := api.Codec.Decode(data) obj2, err := runtime.Decode(codec, data)
if err != nil { if err != nil {
t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj) t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj)
return nil return nil
......
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package v1 package v1
import ( import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
...@@ -28,9 +27,6 @@ const GroupName = "" ...@@ -28,9 +27,6 @@ const GroupName = ""
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1"} var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1"}
// Codec encodes internal objects to the v1 scheme
var Codec = runtime.CodecFor(api.Scheme, SchemeGroupVersion)
func AddToScheme(scheme *runtime.Scheme) { func AddToScheme(scheme *runtime.Scheme) {
// Add the API to Scheme. // Add the API to Scheme.
addKnownTypes(scheme) addKnownTypes(scheme)
......
...@@ -48803,7 +48803,7 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten ...@@ -48803,7 +48803,7 @@ func (x codecSelfer1234) decSliceruntime_RawExtension(v *[]pkg6_runtime.RawExten
yyrg3828 := len(yyv3828) > 0 yyrg3828 := len(yyv3828) > 0
yyv23828 := yyv3828 yyv23828 := yyv3828
yyrl3828, yyrt3828 = z.DecInferLen(yyl3828, z.DecBasicHandle().MaxInitLen, 24) yyrl3828, yyrt3828 = z.DecInferLen(yyl3828, z.DecBasicHandle().MaxInitLen, 40)
if yyrt3828 { if yyrt3828 {
if yyrl3828 <= cap(yyv3828) { if yyrl3828 <= cap(yyv3828) {
yyv3828 = yyv3828[:yyrl3828] yyv3828 = yyv3828[:yyrl3828]
...@@ -72,7 +72,7 @@ func TestValidateOk(t *testing.T) { ...@@ -72,7 +72,7 @@ func TestValidateOk(t *testing.T) {
for _, test := range tests { for _, test := range tests {
testObj := test.obj testObj := test.obj
apiObjectFuzzer.Fuzz(testObj) apiObjectFuzzer.Fuzz(testObj)
data, err := testapi.Default.Codec().Encode(testObj) data, err := runtime.Encode(testapi.Default.Codec(), testObj)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
......
...@@ -17,8 +17,7 @@ limitations under the License. ...@@ -17,8 +17,7 @@ limitations under the License.
package latest package latest
import ( import (
"k8s.io/kubernetes/pkg/apis/abac/v1beta1" _ "k8s.io/kubernetes/pkg/apis/abac"
_ "k8s.io/kubernetes/pkg/apis/abac/v0"
_ "k8s.io/kubernetes/pkg/apis/abac/v1beta1"
) )
// Codec is the default codec for serializing input that should use the latest supported version.
var Codec = v1beta1.Codec
...@@ -14,11 +14,12 @@ See the License for the specific language governing permissions and ...@@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package api package abac
import ( import (
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime/serializer"
) )
// Group is the API group for abac // Group is the API group for abac
...@@ -27,9 +28,11 @@ const Group = "abac.authorization.kubernetes.io" ...@@ -27,9 +28,11 @@ const Group = "abac.authorization.kubernetes.io"
// Scheme is the default instance of runtime.Scheme to which types in the abac API group are registered. // Scheme is the default instance of runtime.Scheme to which types in the abac API group are registered.
var Scheme = runtime.NewScheme() var Scheme = runtime.NewScheme()
// Codecs provides access to encoding and decoding for the scheme
var Codecs = serializer.NewCodecFactory(Scheme)
func init() { func init() {
Scheme.AddInternalGroupVersion(unversioned.GroupVersion{Group: Group, Version: ""}) Scheme.AddKnownTypes(unversioned.GroupVersion{Group: Group, Version: runtime.APIVersionInternal},
Scheme.AddKnownTypes(unversioned.GroupVersion{Group: Group, Version: ""},
&Policy{}, &Policy{},
) )
} }
......
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package api package abac
import "k8s.io/kubernetes/pkg/api/unversioned" import "k8s.io/kubernetes/pkg/api/unversioned"
......
...@@ -17,7 +17,7 @@ limitations under the License. ...@@ -17,7 +17,7 @@ limitations under the License.
package v0 package v0
import ( import (
"k8s.io/kubernetes/pkg/apis/abac" api "k8s.io/kubernetes/pkg/apis/abac"
"k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/conversion"
) )
......
...@@ -20,7 +20,7 @@ import ( ...@@ -20,7 +20,7 @@ import (
"reflect" "reflect"
"testing" "testing"
"k8s.io/kubernetes/pkg/apis/abac" api "k8s.io/kubernetes/pkg/apis/abac"
"k8s.io/kubernetes/pkg/apis/abac/v0" "k8s.io/kubernetes/pkg/apis/abac/v0"
) )
......
...@@ -18,16 +18,12 @@ package v0 ...@@ -18,16 +18,12 @@ package v0
import ( import (
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/abac" api "k8s.io/kubernetes/pkg/apis/abac"
"k8s.io/kubernetes/pkg/runtime"
) )
// GroupVersion is the API group and version for abac v0 // GroupVersion is the API group and version for abac v0
var GroupVersion = unversioned.GroupVersion{Group: api.Group, Version: "v0"} var GroupVersion = unversioned.GroupVersion{Group: api.Group, Version: "v0"}
// Codec encodes internal objects to the v0 version for the abac group
var Codec = runtime.CodecFor(api.Scheme, GroupVersion)
func init() { func init() {
api.Scheme.AddKnownTypes(GroupVersion, api.Scheme.AddKnownTypes(GroupVersion,
&Policy{}, &Policy{},
......
...@@ -18,16 +18,12 @@ package v1beta1 ...@@ -18,16 +18,12 @@ package v1beta1
import ( import (
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/abac" api "k8s.io/kubernetes/pkg/apis/abac"
"k8s.io/kubernetes/pkg/runtime"
) )
// GroupVersion is the API group and version for abac v1beta1 // GroupVersion is the API group and version for abac v1beta1
var GroupVersion = unversioned.GroupVersion{Group: api.Group, Version: "v1beta1"} var GroupVersion = unversioned.GroupVersion{Group: api.Group, Version: "v1beta1"}
// Codec encodes internal objects to the v1beta1 version for the abac group
var Codec = runtime.CodecFor(api.Scheme, GroupVersion)
func init() { func init() {
api.Scheme.AddKnownTypes(GroupVersion, api.Scheme.AddKnownTypes(GroupVersion,
&Policy{}, &Policy{},
......
...@@ -75,7 +75,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error { ...@@ -75,7 +75,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error {
groupMeta := apimachinery.GroupMeta{ groupMeta := apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion, GroupVersion: preferredExternalVersion,
GroupVersions: externalVersions, GroupVersions: externalVersions,
Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion),
RESTMapper: newRESTMapper(externalVersions), RESTMapper: newRESTMapper(externalVersions),
SelfLinker: runtime.SelfLinker(accessor), SelfLinker: runtime.SelfLinker(accessor),
InterfacesFor: interfacesFor, InterfacesFor: interfacesFor,
...@@ -119,7 +118,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e ...@@ -119,7 +118,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e
switch version { switch version {
case v1beta1.SchemeGroupVersion: case v1beta1.SchemeGroupVersion:
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
Codec: v1beta1.Codec,
ObjectConvertor: api.Scheme, ObjectConvertor: api.Scheme,
MetadataAccessor: accessor, MetadataAccessor: accessor,
}, nil }, nil
......
...@@ -25,7 +25,7 @@ import ( ...@@ -25,7 +25,7 @@ import (
const GroupName = "authorization.k8s.io" const GroupName = "authorization.k8s.io"
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: ""} var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind // Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind { func Kind(kind string) unversioned.GroupKind {
......
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package v1beta1 package v1beta1
import ( import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
...@@ -28,8 +27,6 @@ const GroupName = "authorization.k8s.io" ...@@ -28,8 +27,6 @@ const GroupName = "authorization.k8s.io"
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1beta1"} var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1beta1"}
var Codec = runtime.CodecFor(api.Scheme, SchemeGroupVersion)
func AddToScheme(scheme *runtime.Scheme) { func AddToScheme(scheme *runtime.Scheme) {
// Add the API to Scheme. // Add the API to Scheme.
addKnownTypes(scheme) addKnownTypes(scheme)
......
...@@ -18,51 +18,10 @@ limitations under the License. ...@@ -18,51 +18,10 @@ limitations under the License.
package componentconfig package componentconfig
import ( import api "k8s.io/kubernetes/pkg/api"
api "k8s.io/kubernetes/pkg/api"
unversioned "k8s.io/kubernetes/pkg/api/unversioned"
conversion "k8s.io/kubernetes/pkg/conversion"
)
func deepCopy_unversioned_TypeMeta(in unversioned.TypeMeta, out *unversioned.TypeMeta, c *conversion.Cloner) error {
out.Kind = in.Kind
out.APIVersion = in.APIVersion
return nil
}
func deepCopy_componentconfig_KubeProxyConfiguration(in KubeProxyConfiguration, out *KubeProxyConfiguration, c *conversion.Cloner) error {
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err
}
out.BindAddress = in.BindAddress
out.CleanupIPTables = in.CleanupIPTables
out.HealthzBindAddress = in.HealthzBindAddress
out.HealthzPort = in.HealthzPort
out.HostnameOverride = in.HostnameOverride
out.IPTablesSyncePeriodSeconds = in.IPTablesSyncePeriodSeconds
out.KubeAPIBurst = in.KubeAPIBurst
out.KubeAPIQPS = in.KubeAPIQPS
out.KubeconfigPath = in.KubeconfigPath
out.MasqueradeAll = in.MasqueradeAll
out.Master = in.Master
if in.OOMScoreAdj != nil {
out.OOMScoreAdj = new(int)
*out.OOMScoreAdj = *in.OOMScoreAdj
} else {
out.OOMScoreAdj = nil
}
out.Mode = in.Mode
out.PortRange = in.PortRange
out.ResourceContainer = in.ResourceContainer
out.UDPTimeoutMilliseconds = in.UDPTimeoutMilliseconds
return nil
}
func init() { func init() {
err := api.Scheme.AddGeneratedDeepCopyFuncs( err := api.Scheme.AddGeneratedDeepCopyFuncs()
deepCopy_unversioned_TypeMeta,
deepCopy_componentconfig_KubeProxyConfiguration,
)
if err != nil { if err != nil {
// if one of the deep copy functions is malformed, detect it immediately. // if one of the deep copy functions is malformed, detect it immediately.
panic(err) panic(err)
......
...@@ -75,7 +75,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error { ...@@ -75,7 +75,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error {
groupMeta := apimachinery.GroupMeta{ groupMeta := apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion, GroupVersion: preferredExternalVersion,
GroupVersions: externalVersions, GroupVersions: externalVersions,
Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion),
RESTMapper: newRESTMapper(externalVersions), RESTMapper: newRESTMapper(externalVersions),
SelfLinker: runtime.SelfLinker(accessor), SelfLinker: runtime.SelfLinker(accessor),
InterfacesFor: interfacesFor, InterfacesFor: interfacesFor,
...@@ -104,7 +103,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e ...@@ -104,7 +103,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e
switch version { switch version {
case v1alpha1.SchemeGroupVersion: case v1alpha1.SchemeGroupVersion:
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
Codec: v1alpha1.Codec,
ObjectConvertor: api.Scheme, ObjectConvertor: api.Scheme,
MetadataAccessor: accessor, MetadataAccessor: accessor,
}, nil }, nil
......
...@@ -20,16 +20,18 @@ import ( ...@@ -20,16 +20,18 @@ import (
"encoding/json" "encoding/json"
"testing" "testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/componentconfig" "k8s.io/kubernetes/pkg/apis/componentconfig"
"k8s.io/kubernetes/pkg/runtime"
) )
func TestCodec(t *testing.T) { func TestCodec(t *testing.T) {
daemonSet := componentconfig.KubeProxyConfiguration{} daemonSet := componentconfig.KubeProxyConfiguration{}
// We do want to use package registered rather than testapi here, because we // We do want to use package registered rather than testapi here, because we
// want to test if the package install and package registered work as expected. // want to test if the package install and package registered work as expected.
data, err := registered.GroupOrDie(componentconfig.GroupName).Codec.Encode(&daemonSet) data, err := runtime.Encode(api.Codecs.LegacyCodec(registered.GroupOrDie(componentconfig.GroupName).GroupVersion), &daemonSet)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
...@@ -80,8 +82,8 @@ func TestRESTMapper(t *testing.T) { ...@@ -80,8 +82,8 @@ func TestRESTMapper(t *testing.T) {
} }
interfaces, _ := registered.GroupOrDie(componentconfig.GroupName).InterfacesFor(version) interfaces, _ := registered.GroupOrDie(componentconfig.GroupName).InterfacesFor(version)
if mapping.Codec != interfaces.Codec { if mapping.ObjectConvertor != interfaces.ObjectConvertor {
t.Errorf("unexpected codec: %#v, expected: %#v", mapping, interfaces) t.Errorf("unexpected: %#v, expected: %#v", mapping, interfaces)
} }
} }
} }
...@@ -29,7 +29,7 @@ func AddToScheme(scheme *runtime.Scheme) { ...@@ -29,7 +29,7 @@ func AddToScheme(scheme *runtime.Scheme) {
const GroupName = "componentconfig" const GroupName = "componentconfig"
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: ""} var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind // Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind { func Kind(kind string) unversioned.GroupKind {
......
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package v1alpha1 package v1alpha1
import ( import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
...@@ -28,8 +27,6 @@ const GroupName = "componentconfig" ...@@ -28,8 +27,6 @@ const GroupName = "componentconfig"
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1alpha1"} var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1alpha1"}
var Codec = runtime.CodecFor(api.Scheme, SchemeGroupVersion)
func AddToScheme(scheme *runtime.Scheme) { func AddToScheme(scheme *runtime.Scheme) {
addKnownTypes(scheme) addKnownTypes(scheme)
addDefaultingFuncs(scheme) addDefaultingFuncs(scheme)
......
...@@ -75,7 +75,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error { ...@@ -75,7 +75,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error {
groupMeta := apimachinery.GroupMeta{ groupMeta := apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion, GroupVersion: preferredExternalVersion,
GroupVersions: externalVersions, GroupVersions: externalVersions,
Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion),
RESTMapper: newRESTMapper(externalVersions), RESTMapper: newRESTMapper(externalVersions),
SelfLinker: runtime.SelfLinker(accessor), SelfLinker: runtime.SelfLinker(accessor),
InterfacesFor: interfacesFor, InterfacesFor: interfacesFor,
...@@ -104,7 +103,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e ...@@ -104,7 +103,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e
switch version { switch version {
case v1beta1.SchemeGroupVersion: case v1beta1.SchemeGroupVersion:
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
Codec: v1beta1.Codec,
ObjectConvertor: api.Scheme, ObjectConvertor: api.Scheme,
MetadataAccessor: accessor, MetadataAccessor: accessor,
}, nil }, nil
......
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
"k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/runtime"
) )
func TestResourceVersioner(t *testing.T) { func TestResourceVersioner(t *testing.T) {
...@@ -51,7 +52,7 @@ func TestCodec(t *testing.T) { ...@@ -51,7 +52,7 @@ func TestCodec(t *testing.T) {
daemonSet := extensions.DaemonSet{} daemonSet := extensions.DaemonSet{}
// We do want to use package registered rather than testapi here, because we // We do want to use package registered rather than testapi here, because we
// want to test if the package install and package registered work as expected. // want to test if the package install and package registered work as expected.
data, err := registered.GroupOrDie(extensions.GroupName).Codec.Encode(&daemonSet) data, err := runtime.Encode(api.Codecs.LegacyCodec(registered.GroupOrDie(extensions.GroupName).GroupVersion), &daemonSet)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
...@@ -102,8 +103,8 @@ func TestRESTMapper(t *testing.T) { ...@@ -102,8 +103,8 @@ func TestRESTMapper(t *testing.T) {
} }
interfaces, _ := registered.GroupOrDie(extensions.GroupName).InterfacesFor(version) interfaces, _ := registered.GroupOrDie(extensions.GroupName).InterfacesFor(version)
if mapping.Codec != interfaces.Codec { if mapping.ObjectConvertor != interfaces.ObjectConvertor {
t.Errorf("unexpected codec: %#v, expected: %#v", mapping, interfaces) t.Errorf("unexpected: %#v, expected: %#v", mapping, interfaces)
} }
rc := &extensions.HorizontalPodAutoscaler{ObjectMeta: api.ObjectMeta{Name: "foo"}} rc := &extensions.HorizontalPodAutoscaler{ObjectMeta: api.ObjectMeta{Name: "foo"}}
......
...@@ -26,7 +26,7 @@ import ( ...@@ -26,7 +26,7 @@ import (
const GroupName = "extensions" const GroupName = "extensions"
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: ""} var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind // Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind { func Kind(kind string) unversioned.GroupKind {
......
...@@ -588,12 +588,12 @@ func TestDefaultRequestIsNotSetForReplicaSet(t *testing.T) { ...@@ -588,12 +588,12 @@ func TestDefaultRequestIsNotSetForReplicaSet(t *testing.T) {
} }
func roundTrip(t *testing.T, obj runtime.Object) runtime.Object { func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
data, err := runtime.Encode(Codec, obj) data, err := runtime.Encode(api.Codecs.LegacyCodec(SchemeGroupVersion), obj)
if err != nil { if err != nil {
t.Errorf("%v\n %#v", err, obj) t.Errorf("%v\n %#v", err, obj)
return nil return nil
} }
obj2, err := api.Codec.Decode(data) obj2, err := runtime.Decode(api.Codecs.UniversalDecoder(), data)
if err != nil { if err != nil {
t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj) t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj)
return nil return nil
......
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package v1beta1 package v1beta1
import ( import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
...@@ -29,8 +28,6 @@ const GroupName = "extensions" ...@@ -29,8 +28,6 @@ const GroupName = "extensions"
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1beta1"} var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1beta1"}
var Codec = runtime.CodecFor(api.Scheme, SchemeGroupVersion)
func AddToScheme(scheme *runtime.Scheme) { func AddToScheme(scheme *runtime.Scheme) {
addKnownTypes(scheme) addKnownTypes(scheme)
addDefaultingFuncs(scheme) addDefaultingFuncs(scheme)
......
...@@ -18,38 +18,10 @@ limitations under the License. ...@@ -18,38 +18,10 @@ limitations under the License.
package metrics package metrics
import ( import api "k8s.io/kubernetes/pkg/api"
api "k8s.io/kubernetes/pkg/api"
unversioned "k8s.io/kubernetes/pkg/api/unversioned"
conversion "k8s.io/kubernetes/pkg/conversion"
)
func deepCopy_unversioned_TypeMeta(in unversioned.TypeMeta, out *unversioned.TypeMeta, c *conversion.Cloner) error {
out.Kind = in.Kind
out.APIVersion = in.APIVersion
return nil
}
func deepCopy_metrics_RawNode(in RawNode, out *RawNode, c *conversion.Cloner) error {
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err
}
return nil
}
func deepCopy_metrics_RawPod(in RawPod, out *RawPod, c *conversion.Cloner) error {
if err := deepCopy_unversioned_TypeMeta(in.TypeMeta, &out.TypeMeta, c); err != nil {
return err
}
return nil
}
func init() { func init() {
err := api.Scheme.AddGeneratedDeepCopyFuncs( err := api.Scheme.AddGeneratedDeepCopyFuncs()
deepCopy_unversioned_TypeMeta,
deepCopy_metrics_RawNode,
deepCopy_metrics_RawPod,
)
if err != nil { if err != nil {
// if one of the deep copy functions is malformed, detect it immediately. // if one of the deep copy functions is malformed, detect it immediately.
panic(err) panic(err)
......
...@@ -75,7 +75,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error { ...@@ -75,7 +75,6 @@ func enableVersions(externalVersions []unversioned.GroupVersion) error {
groupMeta := apimachinery.GroupMeta{ groupMeta := apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion, GroupVersion: preferredExternalVersion,
GroupVersions: externalVersions, GroupVersions: externalVersions,
Codec: runtime.CodecFor(api.Scheme, preferredExternalVersion),
RESTMapper: newRESTMapper(externalVersions), RESTMapper: newRESTMapper(externalVersions),
SelfLinker: runtime.SelfLinker(accessor), SelfLinker: runtime.SelfLinker(accessor),
InterfacesFor: interfacesFor, InterfacesFor: interfacesFor,
...@@ -104,7 +103,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e ...@@ -104,7 +103,6 @@ func interfacesFor(version unversioned.GroupVersion) (*meta.VersionInterfaces, e
switch version { switch version {
case v1alpha1.SchemeGroupVersion: case v1alpha1.SchemeGroupVersion:
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
Codec: v1alpha1.Codec,
ObjectConvertor: api.Scheme, ObjectConvertor: api.Scheme,
MetadataAccessor: accessor, MetadataAccessor: accessor,
}, nil }, nil
......
...@@ -30,7 +30,7 @@ func AddToScheme(scheme *runtime.Scheme) { ...@@ -30,7 +30,7 @@ func AddToScheme(scheme *runtime.Scheme) {
const GroupName = "metrics" const GroupName = "metrics"
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: ""} var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
// Kind takes an unqualified kind and returns back a Group qualified GroupKind // Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) unversioned.GroupKind { func Kind(kind string) unversioned.GroupKind {
......
...@@ -17,7 +17,6 @@ limitations under the License. ...@@ -17,7 +17,6 @@ limitations under the License.
package v1alpha1 package v1alpha1
import ( import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
...@@ -29,8 +28,6 @@ const GroupName = "metrics" ...@@ -29,8 +28,6 @@ const GroupName = "metrics"
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1alpha1"} var SchemeGroupVersion = unversioned.GroupVersion{Group: GroupName, Version: "v1alpha1"}
var Codec = runtime.CodecFor(api.Scheme, SchemeGroupVersion)
func AddToScheme(scheme *runtime.Scheme) { func AddToScheme(scheme *runtime.Scheme) {
// Add the API to Scheme. // Add the API to Scheme.
addKnownTypes(scheme) addKnownTypes(scheme)
......
...@@ -65,7 +65,13 @@ var errEmptyName = errors.NewBadRequest("name must be provided") ...@@ -65,7 +65,13 @@ var errEmptyName = errors.NewBadRequest("name must be provided")
func (a *APIInstaller) Install(ws *restful.WebService) (apiResources []unversioned.APIResource, errors []error) { func (a *APIInstaller) Install(ws *restful.WebService) (apiResources []unversioned.APIResource, errors []error) {
errors = make([]error, 0) errors = make([]error, 0)
proxyHandler := (&ProxyHandler{a.prefix + "/proxy/", a.group.Storage, a.group.Codec, a.group.Context, a.info}) proxyHandler := (&ProxyHandler{
prefix: a.prefix + "/proxy/",
storage: a.group.Storage,
serializer: a.group.Serializer,
context: a.group.Context,
requestInfoResolver: a.info,
})
// Register the paths in a deterministic (sorted) order to get a deterministic swagger spec. // Register the paths in a deterministic (sorted) order to get a deterministic swagger spec.
paths := make([]string, len(a.group.Storage)) paths := make([]string, len(a.group.Storage))
...@@ -93,9 +99,11 @@ func (a *APIInstaller) NewWebService() *restful.WebService { ...@@ -93,9 +99,11 @@ func (a *APIInstaller) NewWebService() *restful.WebService {
ws.Path(a.prefix) ws.Path(a.prefix)
// a.prefix contains "prefix/group/version" // a.prefix contains "prefix/group/version"
ws.Doc("API at " + a.prefix) ws.Doc("API at " + a.prefix)
// TODO: change to restful.MIME_JSON when we set content type in client // Backwards compatibilty, we accepted objects with empty content-type at V1.
// If we stop using go-restful, we can default empty content-type to application/json on an
// endpoint by endpoint basis
ws.Consumes("*/*") ws.Consumes("*/*")
ws.Produces(restful.MIME_JSON) ws.Produces(a.group.Serializer.SupportedMediaTypes()...)
ws.ApiVersion(a.group.GroupVersion.String()) ws.ApiVersion(a.group.GroupVersion.String())
return ws return ws
...@@ -262,19 +270,14 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -262,19 +270,14 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
getOptions runtime.Object getOptions runtime.Object
versionedGetOptions runtime.Object versionedGetOptions runtime.Object
getOptionsInternalKind unversioned.GroupVersionKind getOptionsInternalKind unversioned.GroupVersionKind
getOptionsExternalKind unversioned.GroupVersionKind
getSubpath bool getSubpath bool
getSubpathKey string
) )
if isGetterWithOptions { if isGetterWithOptions {
getOptions, getSubpath, getSubpathKey = getterWithOptions.NewGetOptions() getOptions, getSubpath, _ = getterWithOptions.NewGetOptions()
getOptionsInternalKind, err = a.group.Typer.ObjectKind(getOptions) getOptionsInternalKind, err = a.group.Typer.ObjectKind(getOptions)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// TODO this should be a list of all the different external versions we can coerce into the internalKind
getOptionsExternalKind = optionsExternalVersion.WithKind(getOptionsInternalKind.Kind)
versionedGetOptions, err = a.group.Creater.New(optionsExternalVersion.WithKind(getOptionsInternalKind.Kind)) versionedGetOptions, err = a.group.Creater.New(optionsExternalVersion.WithKind(getOptionsInternalKind.Kind))
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -286,19 +289,15 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -286,19 +289,15 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
connectOptions runtime.Object connectOptions runtime.Object
versionedConnectOptions runtime.Object versionedConnectOptions runtime.Object
connectOptionsInternalKind unversioned.GroupVersionKind connectOptionsInternalKind unversioned.GroupVersionKind
connectOptionsExternalKind unversioned.GroupVersionKind
connectSubpath bool connectSubpath bool
connectSubpathKey string
) )
if isConnecter { if isConnecter {
connectOptions, connectSubpath, connectSubpathKey = connecter.NewConnectOptions() connectOptions, connectSubpath, _ = connecter.NewConnectOptions()
if connectOptions != nil { if connectOptions != nil {
connectOptionsInternalKind, err = a.group.Typer.ObjectKind(connectOptions) connectOptionsInternalKind, err = a.group.Typer.ObjectKind(connectOptions)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// TODO this should be a list of all the different external versions we can coerce into the internalKind
connectOptionsExternalKind = optionsExternalVersion.WithKind(connectOptionsInternalKind.Kind)
versionedConnectOptions, err = a.group.Creater.New(optionsExternalVersion.WithKind(connectOptionsInternalKind.Kind)) versionedConnectOptions, err = a.group.Creater.New(optionsExternalVersion.WithKind(connectOptionsInternalKind.Kind))
} }
...@@ -434,10 +433,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -434,10 +433,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
// test/integration/auth_test.go is currently the most comprehensive status code test // test/integration/auth_test.go is currently the most comprehensive status code test
reqScope := RequestScope{ reqScope := RequestScope{
ContextFunc: ctxFn, ContextFunc: ctxFn,
Creater: a.group.Creater, Serializer: a.group.Serializer,
Convertor: a.group.Convertor, ParameterCodec: a.group.ParameterCodec,
Codec: mapping.Codec, Creater: a.group.Creater,
Convertor: a.group.Convertor,
Resource: a.group.GroupVersion.WithResource(resource), Resource: a.group.GroupVersion.WithResource(resource),
Subresource: subresource, Subresource: subresource,
...@@ -454,7 +454,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -454,7 +454,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
case "GET": // Get a resource. case "GET": // Get a resource.
var handler restful.RouteFunction var handler restful.RouteFunction
if isGetterWithOptions { if isGetterWithOptions {
handler = GetResourceWithOptions(getterWithOptions, exporter, reqScope, getOptionsInternalKind, getOptionsExternalKind, getSubpath, getSubpathKey) handler = GetResourceWithOptions(getterWithOptions, reqScope)
} else { } else {
handler = GetResource(getter, exporter, reqScope) handler = GetResource(getter, exporter, reqScope)
} }
...@@ -467,7 +467,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -467,7 +467,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
Operation("read"+namespaced+kind+strings.Title(subresource)). Operation("read"+namespaced+kind+strings.Title(subresource)).
Produces(append(storageMeta.ProducesMIMETypes(action.Verb), "application/json")...). Produces(append(storageMeta.ProducesMIMETypes(action.Verb), a.group.Serializer.SupportedMediaTypes()...)...).
Returns(http.StatusOK, "OK", versionedObject). Returns(http.StatusOK, "OK", versionedObject).
Writes(versionedObject) Writes(versionedObject)
if isGetterWithOptions { if isGetterWithOptions {
...@@ -492,7 +492,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -492,7 +492,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
Operation("list"+namespaced+kind+strings.Title(subresource)). Operation("list"+namespaced+kind+strings.Title(subresource)).
Produces("application/json"). Produces(append(storageMeta.ProducesMIMETypes(action.Verb), a.group.Serializer.SupportedMediaTypes()...)...).
Returns(http.StatusOK, "OK", versionedList). Returns(http.StatusOK, "OK", versionedList).
Writes(versionedList) Writes(versionedList)
if err := addObjectParams(ws, route, versionedListOptions); err != nil { if err := addObjectParams(ws, route, versionedListOptions); err != nil {
...@@ -524,7 +524,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -524,7 +524,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
Operation("replace"+namespaced+kind+strings.Title(subresource)). Operation("replace"+namespaced+kind+strings.Title(subresource)).
Produces(append(storageMeta.ProducesMIMETypes(action.Verb), "application/json")...). Produces(append(storageMeta.ProducesMIMETypes(action.Verb), a.group.Serializer.SupportedMediaTypes()...)...).
Returns(http.StatusOK, "OK", versionedObject). Returns(http.StatusOK, "OK", versionedObject).
Reads(versionedObject). Reads(versionedObject).
Writes(versionedObject) Writes(versionedObject)
...@@ -541,7 +541,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -541,7 +541,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
Consumes(string(api.JSONPatchType), string(api.MergePatchType), string(api.StrategicMergePatchType)). Consumes(string(api.JSONPatchType), string(api.MergePatchType), string(api.StrategicMergePatchType)).
Operation("patch"+namespaced+kind+strings.Title(subresource)). Operation("patch"+namespaced+kind+strings.Title(subresource)).
Produces(append(storageMeta.ProducesMIMETypes(action.Verb), "application/json")...). Produces(append(storageMeta.ProducesMIMETypes(action.Verb), a.group.Serializer.SupportedMediaTypes()...)...).
Returns(http.StatusOK, "OK", versionedObject). Returns(http.StatusOK, "OK", versionedObject).
Reads(unversioned.Patch{}). Reads(unversioned.Patch{}).
Writes(versionedObject) Writes(versionedObject)
...@@ -563,7 +563,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -563,7 +563,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
Operation("create"+namespaced+kind+strings.Title(subresource)). Operation("create"+namespaced+kind+strings.Title(subresource)).
Produces(append(storageMeta.ProducesMIMETypes(action.Verb), "application/json")...). Produces(append(storageMeta.ProducesMIMETypes(action.Verb), a.group.Serializer.SupportedMediaTypes()...)...).
Returns(http.StatusOK, "OK", versionedObject). Returns(http.StatusOK, "OK", versionedObject).
Reads(versionedObject). Reads(versionedObject).
Writes(versionedObject) Writes(versionedObject)
...@@ -579,7 +579,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -579,7 +579,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
Operation("delete"+namespaced+kind+strings.Title(subresource)). Operation("delete"+namespaced+kind+strings.Title(subresource)).
Produces(append(storageMeta.ProducesMIMETypes(action.Verb), "application/json")...). Produces(append(storageMeta.ProducesMIMETypes(action.Verb), a.group.Serializer.SupportedMediaTypes()...)...).
Writes(versionedStatus). Writes(versionedStatus).
Returns(http.StatusOK, "OK", versionedStatus) Returns(http.StatusOK, "OK", versionedStatus)
if isGracefulDeleter { if isGracefulDeleter {
...@@ -597,7 +597,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -597,7 +597,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
Operation("deletecollection"+namespaced+kind+strings.Title(subresource)). Operation("deletecollection"+namespaced+kind+strings.Title(subresource)).
Produces(append(storageMeta.ProducesMIMETypes(action.Verb), "application/json")...). Produces(append(storageMeta.ProducesMIMETypes(action.Verb), a.group.Serializer.SupportedMediaTypes()...)...).
Writes(versionedStatus). Writes(versionedStatus).
Returns(http.StatusOK, "OK", versionedStatus) Returns(http.StatusOK, "OK", versionedStatus)
if err := addObjectParams(ws, route, versionedListOptions); err != nil { if err := addObjectParams(ws, route, versionedListOptions); err != nil {
...@@ -658,7 +658,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -658,7 +658,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
doc = "connect " + method + " requests to " + subresource + " of " + kind doc = "connect " + method + " requests to " + subresource + " of " + kind
} }
route := ws.Method(method).Path(action.Path). route := ws.Method(method).Path(action.Path).
To(ConnectResource(connecter, reqScope, admit, connectOptionsInternalKind, connectOptionsExternalKind, path, connectSubpath, connectSubpathKey)). To(ConnectResource(connecter, reqScope, admit, path)).
Filter(m). Filter(m).
Doc(doc). Doc(doc).
Operation("connect" + strings.Title(strings.ToLower(method)) + namespaced + kind + strings.Title(subresource)). Operation("connect" + strings.Title(strings.ToLower(method)) + namespaced + kind + strings.Title(subresource)).
......
...@@ -19,6 +19,7 @@ package apiserver ...@@ -19,6 +19,7 @@ package apiserver
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"strings"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
...@@ -105,3 +106,41 @@ func IsAPIPrefixNotFound(err error) bool { ...@@ -105,3 +106,41 @@ func IsAPIPrefixNotFound(err error) bool {
_, ok := err.(*errAPIPrefixNotFound) _, ok := err.(*errAPIPrefixNotFound)
return ok return ok
} }
// errNotAcceptable indicates Accept negotiation has failed
// TODO: move to api/errors if other code needs to return this
type errNotAcceptable struct {
accepted []string
}
func (e errNotAcceptable) Error() string {
return fmt.Sprintf("only the following media types are accepted: %v", strings.Join(e.accepted, ", "))
}
func (e errNotAcceptable) Status() unversioned.Status {
return unversioned.Status{
Status: unversioned.StatusFailure,
Code: http.StatusNotAcceptable,
Reason: unversioned.StatusReason("NotAcceptable"),
Message: e.Error(),
}
}
// errNotAcceptable indicates Content-Type is not recognized
// TODO: move to api/errors if other code needs to return this
type errUnsupportedMediaType struct {
accepted []string
}
func (e errUnsupportedMediaType) Error() string {
return fmt.Sprintf("the body of the request was in an unknown format - accepted media types include: %v", strings.Join(e.accepted, ", "))
}
func (e errUnsupportedMediaType) Status() unversioned.Status {
return unversioned.Status{
Status: unversioned.StatusFailure,
Code: http.StatusUnsupportedMediaType,
Reason: unversioned.StatusReason("UnsupportedMediaType"),
Message: e.Error(),
}
}
/*
Copyright 2015 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 apiserver
import (
"mime"
"net/http"
"strconv"
"strings"
"bitbucket.org/ww/goautoneg"
"k8s.io/kubernetes/pkg/runtime"
)
func negotiateOutputSerializer(req *http.Request, ns runtime.NegotiatedSerializer) (runtime.Serializer, string, error) {
acceptHeader := req.Header.Get("Accept")
supported := ns.SupportedMediaTypes()
if len(acceptHeader) == 0 && len(supported) > 0 {
acceptHeader = supported[0]
}
accept, ok := negotiate(acceptHeader, supported)
if !ok {
return nil, "", errNotAcceptable{supported}
}
pretty := isPrettyPrint(req)
if _, ok := accept.Params["pretty"]; !ok && pretty {
accept.Params["pretty"] = "1"
}
mediaType := accept.Type
if len(accept.SubType) > 0 {
mediaType += "/" + accept.SubType
}
if s, ok := ns.SerializerForMediaType(mediaType, accept.Params); ok {
return s, mediaType, nil
}
return nil, "", errNotAcceptable{supported}
}
func negotiateInputSerializer(req *http.Request, s runtime.NegotiatedSerializer) (runtime.Serializer, error) {
supported := s.SupportedMediaTypes()
mediaType := req.Header.Get("Content-Type")
if len(mediaType) == 0 {
mediaType = supported[0]
}
mediaType, options, err := mime.ParseMediaType(mediaType)
if err != nil {
return nil, errUnsupportedMediaType{supported}
}
out, ok := s.SerializerForMediaType(mediaType, options)
if !ok {
return nil, errUnsupportedMediaType{supported}
}
return out, nil
}
// isPrettyPrint returns true if the "pretty" query parameter is true or if the User-Agent
// matches known "human" clients.
func isPrettyPrint(req *http.Request) bool {
// DEPRECATED: should be part of the content type
if req.URL != nil {
pp := req.URL.Query().Get("pretty")
if len(pp) > 0 {
pretty, _ := strconv.ParseBool(pp)
return pretty
}
}
userAgent := req.UserAgent()
// This covers basic all browers and cli http tools
if strings.HasPrefix(userAgent, "curl") || strings.HasPrefix(userAgent, "Wget") || strings.HasPrefix(userAgent, "Mozilla/5.0") {
return true
}
return false
}
// negotiate the most appropriate content type given the accept header and a list of
// alternatives.
func negotiate(header string, alternatives []string) (goautoneg.Accept, bool) {
alternates := make([][]string, 0, len(alternatives))
for _, alternate := range alternatives {
alternates = append(alternates, strings.SplitN(alternate, "/", 2))
}
for _, clause := range goautoneg.ParseAccept(header) {
for _, alternate := range alternates {
if clause.Type == alternate[0] && clause.SubType == alternate[1] {
return clause, true
}
if clause.Type == alternate[0] && clause.SubType == "*" {
clause.SubType = alternate[1]
return clause, true
}
if clause.Type == "*" && clause.SubType == "*" {
clause.Type = alternate[0]
clause.SubType = alternate[1]
return clause, true
}
}
}
return goautoneg.Accept{}, false
}
/*
Copyright 2015 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 apiserver
import (
"net/http"
"net/url"
"reflect"
"testing"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
)
type fakeNegotiater struct {
serializer runtime.Serializer
types []string
mediaType string
options map[string]string
}
func (n *fakeNegotiater) SupportedMediaTypes() []string {
return n.types
}
func (n *fakeNegotiater) SerializerForMediaType(mediaType string, options map[string]string) (runtime.Serializer, bool) {
n.mediaType = mediaType
if len(options) > 0 {
n.options = options
}
return n.serializer, n.serializer != nil
}
func (n *fakeNegotiater) EncoderForVersion(serializer runtime.Serializer, gv unversioned.GroupVersion) runtime.Encoder {
return n.serializer
}
func (n *fakeNegotiater) DecoderToVersion(serializer runtime.Serializer, gv unversioned.GroupVersion) runtime.Decoder {
return n.serializer
}
var fakeCodec = runtime.NewCodec(runtime.NoopEncoder{}, runtime.NoopDecoder{})
func TestNegotiate(t *testing.T) {
testCases := []struct {
accept string
req *http.Request
ns *fakeNegotiater
serializer runtime.Serializer
contentType string
params map[string]string
errFn func(error) bool
}{
// pick a default
{
req: &http.Request{},
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
serializer: fakeCodec,
},
{
accept: "",
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
serializer: fakeCodec,
},
{
accept: "*/*",
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
serializer: fakeCodec,
},
{
accept: "application/*",
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
serializer: fakeCodec,
},
{
accept: "application/json",
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
serializer: fakeCodec,
},
{
accept: "application/json",
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json", "application/protobuf"}},
serializer: fakeCodec,
},
{
accept: "application/protobuf",
contentType: "application/protobuf",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json", "application/protobuf"}},
serializer: fakeCodec,
},
{
accept: "application/json; pretty=1",
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
serializer: fakeCodec,
params: map[string]string{"pretty": "1"},
},
{
accept: "unrecognized/stuff,application/json; pretty=1",
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
serializer: fakeCodec,
params: map[string]string{"pretty": "1"},
},
// query param triggers pretty
{
req: &http.Request{
Header: http.Header{"Accept": []string{"application/json"}},
URL: &url.URL{RawQuery: "pretty=1"},
},
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
serializer: fakeCodec,
params: map[string]string{"pretty": "1"},
},
// certain user agents trigger pretty
{
req: &http.Request{
Header: http.Header{
"Accept": []string{"application/json"},
"User-Agent": []string{"curl"},
},
},
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
serializer: fakeCodec,
params: map[string]string{"pretty": "1"},
},
{
req: &http.Request{
Header: http.Header{
"Accept": []string{"application/json"},
"User-Agent": []string{"Wget"},
},
},
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
serializer: fakeCodec,
params: map[string]string{"pretty": "1"},
},
{
req: &http.Request{
Header: http.Header{
"Accept": []string{"application/json"},
"User-Agent": []string{"Mozilla/5.0"},
},
},
contentType: "application/json",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application/json"}},
serializer: fakeCodec,
params: map[string]string{"pretty": "1"},
},
// "application" is not a valid media type, so the server will reject the response during
// negotiation (the server, in error, has specified an invalid media type)
{
accept: "application",
ns: &fakeNegotiater{serializer: fakeCodec, types: []string{"application"}},
errFn: func(err error) bool {
return err.Error() == "only the following media types are accepted: application"
},
},
{
ns: &fakeNegotiater{types: []string{"a/b/c"}},
errFn: func(err error) bool {
return err.Error() == "only the following media types are accepted: a/b/c"
},
},
{
ns: &fakeNegotiater{},
errFn: func(err error) bool {
return err.Error() == "only the following media types are accepted: "
},
},
{
accept: "*/*",
ns: &fakeNegotiater{},
errFn: func(err error) bool {
return err.Error() == "only the following media types are accepted: "
},
},
{
accept: "application/json",
ns: &fakeNegotiater{types: []string{"application/json"}},
errFn: func(err error) bool {
return err.Error() == "only the following media types are accepted: application/json"
},
},
}
for i, test := range testCases {
req := test.req
if req == nil {
req = &http.Request{Header: http.Header{}}
req.Header.Set("Accept", test.accept)
}
s, contentType, err := negotiateOutputSerializer(req, test.ns)
switch {
case err == nil && test.errFn != nil:
t.Errorf("%d: failed: expected error", i)
continue
case err != nil && test.errFn == nil:
t.Errorf("%d: failed: %v", i, err)
continue
case err != nil:
if !test.errFn(err) {
t.Errorf("%d: failed: %v", i, err)
}
status, ok := err.(statusError)
if !ok {
t.Errorf("%d: failed, error should be statusError: %v", i, err)
continue
}
if status.Status().Status != unversioned.StatusFailure || status.Status().Code != http.StatusNotAcceptable {
t.Errorf("%d: failed: %v", i, err)
continue
}
continue
}
if test.contentType != contentType {
t.Errorf("%d: unexpected %s %s", i, test.contentType, contentType)
}
if s != test.serializer {
t.Errorf("%d: unexpected %s %s", i, test.serializer, s)
}
if !reflect.DeepEqual(test.params, test.ns.options) {
t.Errorf("%d: unexpected %#v %#v", i, test.params, test.ns.options)
}
}
}
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apiserver/metrics" "k8s.io/kubernetes/pkg/apiserver/metrics"
"k8s.io/kubernetes/pkg/httplog" "k8s.io/kubernetes/pkg/httplog"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
...@@ -44,7 +45,7 @@ import ( ...@@ -44,7 +45,7 @@ import (
type ProxyHandler struct { type ProxyHandler struct {
prefix string prefix string
storage map[string]rest.Storage storage map[string]rest.Storage
codec runtime.Codec serializer runtime.NegotiatedSerializer
context api.RequestContextMapper context api.RequestContextMapper
requestInfoResolver *RequestInfoResolver requestInfoResolver *RequestInfoResolver
} }
...@@ -98,20 +99,19 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -98,20 +99,19 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
apiResource = resource apiResource = resource
gv := unversioned.GroupVersion{Group: requestInfo.APIGroup, Version: requestInfo.APIVersion}
redirector, ok := storage.(rest.Redirector) redirector, ok := storage.(rest.Redirector)
if !ok { if !ok {
httplog.LogOf(req, w).Addf("'%v' is not a redirector", resource) httplog.LogOf(req, w).Addf("'%v' is not a redirector", resource)
httpCode = errorJSON(errors.NewMethodNotSupported(api.Resource(resource), "proxy"), r.codec, w) httpCode = errorNegotiated(errors.NewMethodNotSupported(api.Resource(resource), "proxy"), r.serializer, gv, w, req)
return return
} }
location, roundTripper, err := redirector.ResourceLocation(ctx, id) location, roundTripper, err := redirector.ResourceLocation(ctx, id)
if err != nil { if err != nil {
httplog.LogOf(req, w).Addf("Error getting ResourceLocation: %v", err) httplog.LogOf(req, w).Addf("Error getting ResourceLocation: %v", err)
status := errToAPIStatus(err) httpCode = errorNegotiated(err, r.serializer, gv, w, req)
code := int(status.Code)
writeJSON(code, r.codec, status, w, true)
httpCode = code
return return
} }
if location == nil { if location == nil {
...@@ -144,11 +144,7 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -144,11 +144,7 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
newReq, err := http.NewRequest(req.Method, location.String(), req.Body) newReq, err := http.NewRequest(req.Method, location.String(), req.Body)
if err != nil { if err != nil {
status := errToAPIStatus(err) httpCode = errorNegotiated(err, r.serializer, gv, w, req)
code := int(status.Code)
writeJSON(code, r.codec, status, w, true)
notFound(w, req)
httpCode = code
return return
} }
httpCode = http.StatusOK httpCode = http.StatusOK
...@@ -161,7 +157,7 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -161,7 +157,7 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// TODO convert this entire proxy to an UpgradeAwareProxy similar to // TODO convert this entire proxy to an UpgradeAwareProxy similar to
// https://github.com/openshift/origin/blob/master/pkg/util/httpproxy/upgradeawareproxy.go. // https://github.com/openshift/origin/blob/master/pkg/util/httpproxy/upgradeawareproxy.go.
// That proxy needs to be modified to support multiple backends, not just 1. // That proxy needs to be modified to support multiple backends, not just 1.
if r.tryUpgrade(w, req, newReq, location, roundTripper) { if r.tryUpgrade(w, req, newReq, location, roundTripper, gv) {
return return
} }
...@@ -210,15 +206,13 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -210,15 +206,13 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
// tryUpgrade returns true if the request was handled. // tryUpgrade returns true if the request was handled.
func (r *ProxyHandler) tryUpgrade(w http.ResponseWriter, req, newReq *http.Request, location *url.URL, transport http.RoundTripper) bool { func (r *ProxyHandler) tryUpgrade(w http.ResponseWriter, req, newReq *http.Request, location *url.URL, transport http.RoundTripper, gv unversioned.GroupVersion) bool {
if !httpstream.IsUpgradeRequest(req) { if !httpstream.IsUpgradeRequest(req) {
return false return false
} }
backendConn, err := proxyutil.DialURL(location, transport) backendConn, err := proxyutil.DialURL(location, transport)
if err != nil { if err != nil {
status := errToAPIStatus(err) errorNegotiated(err, r.serializer, gv, w, req)
code := int(status.Code)
writeJSON(code, r.codec, status, w, true)
return true return true
} }
defer backendConn.Close() defer backendConn.Close()
...@@ -228,17 +222,13 @@ func (r *ProxyHandler) tryUpgrade(w http.ResponseWriter, req, newReq *http.Reque ...@@ -228,17 +222,13 @@ func (r *ProxyHandler) tryUpgrade(w http.ResponseWriter, req, newReq *http.Reque
// hijack, just for reference... // hijack, just for reference...
requestHijackedConn, _, err := w.(http.Hijacker).Hijack() requestHijackedConn, _, err := w.(http.Hijacker).Hijack()
if err != nil { if err != nil {
status := errToAPIStatus(err) errorNegotiated(err, r.serializer, gv, w, req)
code := int(status.Code)
writeJSON(code, r.codec, status, w, true)
return true return true
} }
defer requestHijackedConn.Close() defer requestHijackedConn.Close()
if err = newReq.Write(backendConn); err != nil { if err = newReq.Write(backendConn); err != nil {
status := errToAPIStatus(err) errorNegotiated(err, r.serializer, gv, w, req)
code := int(status.Code)
writeJSON(code, r.codec, status, w, true)
return true return true
} }
......
...@@ -28,8 +28,8 @@ import ( ...@@ -28,8 +28,8 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
apierrors "k8s.io/kubernetes/pkg/api/errors" apierrors "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/util/strategicpatch" "k8s.io/kubernetes/pkg/util/strategicpatch"
...@@ -155,7 +155,7 @@ func (tc *patchTestCase) Run(t *testing.T) { ...@@ -155,7 +155,7 @@ func (tc *patchTestCase) Run(t *testing.T) {
namespace := tc.startingPod.Namespace namespace := tc.startingPod.Namespace
name := tc.startingPod.Name name := tc.startingPod.Name
codec := registered.GroupOrDie(api.GroupName).Codec codec := testapi.Default.Codec()
admit := tc.admit admit := tc.admit
if admit == nil { if admit == nil {
admit = func(updatedObject runtime.Object) error { admit = func(updatedObject runtime.Object) error {
......
...@@ -65,23 +65,34 @@ func (w *realTimeoutFactory) TimeoutCh() (<-chan time.Time, func() bool) { ...@@ -65,23 +65,34 @@ func (w *realTimeoutFactory) TimeoutCh() (<-chan time.Time, func() bool) {
} }
// serveWatch handles serving requests to the server // serveWatch handles serving requests to the server
func serveWatch(watcher watch.Interface, scope RequestScope, w http.ResponseWriter, req *restful.Request, timeout time.Duration) { func serveWatch(watcher watch.Interface, scope RequestScope, req *restful.Request, res *restful.Response, timeout time.Duration) {
watchServer := &WatchServer{watcher, scope.Codec, func(obj runtime.Object) { s, mediaType, err := negotiateOutputSerializer(req.Request, scope.Serializer)
if err != nil {
scope.err(err, req, res)
return
}
// TODO: replace with typed serialization
if mediaType != "application/json" {
writeRawJSON(http.StatusNotAcceptable, (errNotAcceptable{[]string{"application/json"}}).Status(), res.ResponseWriter)
return
}
encoder := scope.Serializer.EncoderForVersion(s, scope.Kind.GroupVersion())
watchServer := &WatchServer{watcher, encoder, func(obj runtime.Object) {
if err := setSelfLink(obj, req, scope.Namer); err != nil { if err := setSelfLink(obj, req, scope.Namer); err != nil {
glog.V(5).Infof("Failed to set self link for object %v: %v", reflect.TypeOf(obj), err) glog.V(5).Infof("Failed to set self link for object %v: %v", reflect.TypeOf(obj), err)
} }
}, &realTimeoutFactory{timeout}} }, &realTimeoutFactory{timeout}}
if isWebsocketRequest(req.Request) { if isWebsocketRequest(req.Request) {
websocket.Handler(watchServer.HandleWS).ServeHTTP(httplog.Unlogged(w), req.Request) websocket.Handler(watchServer.HandleWS).ServeHTTP(httplog.Unlogged(res.ResponseWriter), req.Request)
} else { } else {
watchServer.ServeHTTP(w, req.Request) watchServer.ServeHTTP(res.ResponseWriter, req.Request)
} }
} }
// WatchServer serves a watch.Interface over a websocket or vanilla HTTP. // WatchServer serves a watch.Interface over a websocket or vanilla HTTP.
type WatchServer struct { type WatchServer struct {
watching watch.Interface watching watch.Interface
codec runtime.Codec encoder runtime.Encoder
fixup func(runtime.Object) fixup func(runtime.Object)
t timeoutFactory t timeoutFactory
} }
...@@ -108,7 +119,7 @@ func (w *WatchServer) HandleWS(ws *websocket.Conn) { ...@@ -108,7 +119,7 @@ func (w *WatchServer) HandleWS(ws *websocket.Conn) {
return return
} }
w.fixup(event.Object) w.fixup(event.Object)
obj, err := watchjson.Object(w.codec, &event) obj, err := watchjson.Object(w.encoder, &event)
if err != nil { if err != nil {
// Client disconnect. // Client disconnect.
w.watching.Stop() w.watching.Stop()
...@@ -134,20 +145,21 @@ func (self *WatchServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { ...@@ -134,20 +145,21 @@ func (self *WatchServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
cn, ok := w.(http.CloseNotifier) cn, ok := w.(http.CloseNotifier)
if !ok { if !ok {
loggedW.Addf("unable to get CloseNotifier") loggedW.Addf("unable to get CloseNotifier: %#v", w)
http.NotFound(w, req) http.NotFound(w, req)
return return
} }
flusher, ok := w.(http.Flusher) flusher, ok := w.(http.Flusher)
if !ok { if !ok {
loggedW.Addf("unable to get Flusher") loggedW.Addf("unable to get Flusher: %#v", w)
http.NotFound(w, req) http.NotFound(w, req)
return return
} }
w.Header().Set("Transfer-Encoding", "chunked") w.Header().Set("Transfer-Encoding", "chunked")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
flusher.Flush() flusher.Flush()
encoder := watchjson.NewEncoder(w, self.codec) // TODO: use arbitrary serialization on watch
encoder := watchjson.NewEncoder(w, self.encoder)
for { for {
select { select {
case <-cn.CloseNotify(): case <-cn.CloseNotify():
......
...@@ -169,6 +169,34 @@ func TestWatchHTTP(t *testing.T) { ...@@ -169,6 +169,34 @@ func TestWatchHTTP(t *testing.T) {
} }
} }
func TestWatchHTTPAccept(t *testing.T) {
simpleStorage := &SimpleRESTStorage{}
handler := handle(map[string]rest.Storage{"simples": simpleStorage})
server := httptest.NewServer(handler)
defer server.Close()
client := http.Client{}
dest, _ := url.Parse(server.URL)
dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simples"
dest.RawQuery = ""
request, err := http.NewRequest("GET", dest.String(), nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request.Header.Set("Accept", "application/yaml")
response, err := client.Do(request)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// TODO: once this is fixed, this test will change
if response.StatusCode != http.StatusNotAcceptable {
t.Errorf("Unexpected response %#v", response)
}
}
func TestWatchParamParsing(t *testing.T) { func TestWatchParamParsing(t *testing.T) {
simpleStorage := &SimpleRESTStorage{} simpleStorage := &SimpleRESTStorage{}
handler := handle(map[string]rest.Storage{ handler := handle(map[string]rest.Storage{
......
...@@ -28,11 +28,11 @@ import ( ...@@ -28,11 +28,11 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/apis/abac" api "k8s.io/kubernetes/pkg/apis/abac"
"k8s.io/kubernetes/pkg/apis/abac/latest" _ "k8s.io/kubernetes/pkg/apis/abac/latest"
"k8s.io/kubernetes/pkg/apis/abac/v0" "k8s.io/kubernetes/pkg/apis/abac/v0"
_ "k8s.io/kubernetes/pkg/apis/abac/v1beta1"
"k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/auth/authorizer"
"k8s.io/kubernetes/pkg/runtime"
) )
type policyLoadError struct { type policyLoadError struct {
...@@ -64,6 +64,8 @@ func NewFromFile(path string) (policyList, error) { ...@@ -64,6 +64,8 @@ func NewFromFile(path string) (policyList, error) {
scanner := bufio.NewScanner(file) scanner := bufio.NewScanner(file)
pl := make(policyList, 0) pl := make(policyList, 0)
decoder := api.Codecs.UniversalDecoder()
i := 0 i := 0
unversionedLines := 0 unversionedLines := 0
for scanner.Scan() { for scanner.Scan() {
...@@ -77,34 +79,29 @@ func NewFromFile(path string) (policyList, error) { ...@@ -77,34 +79,29 @@ func NewFromFile(path string) (policyList, error) {
continue continue
} }
dataKind, err := api.Scheme.DataKind(b) decodedObj, _, err := decoder.Decode(b, nil, nil)
if err != nil { if err != nil {
return nil, policyLoadError{path, i, b, err} if !(runtime.IsMissingVersion(err) || runtime.IsMissingKind(err) || runtime.IsNotRegisteredError(err)) {
} return nil, policyLoadError{path, i, b, err}
}
if dataKind.IsEmpty() {
unversionedLines++ unversionedLines++
// Migrate unversioned policy object // Migrate unversioned policy object
oldPolicy := &v0.Policy{} oldPolicy := &v0.Policy{}
if err := latest.Codec.DecodeInto(b, oldPolicy); err != nil { if err := runtime.DecodeInto(decoder, b, oldPolicy); err != nil {
return nil, policyLoadError{path, i, b, err} return nil, policyLoadError{path, i, b, err}
} }
if err := api.Scheme.Convert(oldPolicy, p); err != nil { if err := api.Scheme.Convert(oldPolicy, p); err != nil {
return nil, policyLoadError{path, i, b, err} return nil, policyLoadError{path, i, b, err}
} }
} else { pl = append(pl, p)
decodedObj, err := latest.Codec.Decode(b) continue
if err != nil {
return nil, policyLoadError{path, i, b, err}
}
decodedPolicy, ok := decodedObj.(*api.Policy)
if !ok {
return nil, policyLoadError{path, i, b, fmt.Errorf("unrecognized object: %#v", decodedObj)}
}
p = decodedPolicy
} }
pl = append(pl, p) decodedPolicy, ok := decodedObj.(*api.Policy)
if !ok {
return nil, policyLoadError{path, i, b, fmt.Errorf("unrecognized object: %#v", decodedObj)}
}
pl = append(pl, decodedPolicy)
} }
if unversionedLines > 0 { if unversionedLines > 0 {
......
...@@ -21,7 +21,7 @@ import ( ...@@ -21,7 +21,7 @@ import (
"os" "os"
"testing" "testing"
"k8s.io/kubernetes/pkg/apis/abac" api "k8s.io/kubernetes/pkg/apis/abac"
"k8s.io/kubernetes/pkg/apis/abac/v0" "k8s.io/kubernetes/pkg/apis/abac/v0"
"k8s.io/kubernetes/pkg/apis/abac/v1beta1" "k8s.io/kubernetes/pkg/apis/abac/v1beta1"
"k8s.io/kubernetes/pkg/auth/authorizer" "k8s.io/kubernetes/pkg/auth/authorizer"
......
...@@ -128,7 +128,7 @@ type objects struct { ...@@ -128,7 +128,7 @@ type objects struct {
types map[string][]runtime.Object types map[string][]runtime.Object
last map[string]int last map[string]int
scheme ObjectScheme scheme ObjectScheme
decoder runtime.ObjectDecoder decoder runtime.Decoder
} }
var _ ObjectRetriever = &objects{} var _ ObjectRetriever = &objects{}
...@@ -143,7 +143,7 @@ var _ ObjectRetriever = &objects{} ...@@ -143,7 +143,7 @@ var _ ObjectRetriever = &objects{}
// as a runtime.Object if Status == Success). If multiple PodLists are provided, they // as a runtime.Object if Status == Success). If multiple PodLists are provided, they
// will be returned in order by the Kind call, and the last PodList will be reused for // will be returned in order by the Kind call, and the last PodList will be reused for
// subsequent calls. // subsequent calls.
func NewObjects(scheme ObjectScheme, decoder runtime.ObjectDecoder) ObjectRetriever { func NewObjects(scheme ObjectScheme, decoder runtime.Decoder) ObjectRetriever {
return objects{ return objects{
types: make(map[string][]runtime.Object), types: make(map[string][]runtime.Object),
last: make(map[string]int), last: make(map[string]int),
......
...@@ -30,7 +30,7 @@ import ( ...@@ -30,7 +30,7 @@ import (
// Clientset returns a clientset that will respond with the provided objects // Clientset returns a clientset that will respond with the provided objects
func NewSimpleClientset(objects ...runtime.Object) *Clientset { func NewSimpleClientset(objects ...runtime.Object) *Clientset {
o := core.NewObjects(api.Scheme, api.Scheme) o := core.NewObjects(api.Scheme, api.Codecs.UniversalDecoder())
for _, obj := range objects { for _, obj := range objects {
if err := o.Add(obj); err != nil { if err := o.Add(obj); err != nil {
panic(err) panic(err)
......
...@@ -17,7 +17,7 @@ limitations under the License. ...@@ -17,7 +17,7 @@ limitations under the License.
package unversioned package unversioned
import ( import (
"fmt" api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered" registered "k8s.io/kubernetes/pkg/apimachinery/registered"
unversioned "k8s.io/kubernetes/pkg/client/unversioned" unversioned "k8s.io/kubernetes/pkg/client/unversioned"
) )
...@@ -109,12 +109,7 @@ func setConfigDefaults(config *unversioned.Config) error { ...@@ -109,12 +109,7 @@ func setConfigDefaults(config *unversioned.Config) error {
config.GroupVersion = &copyGroupVersion config.GroupVersion = &copyGroupVersion
//} //}
versionInterfaces, err := g.InterfacesFor(*config.GroupVersion) config.Codec = api.Codecs.LegacyCodec(*config.GroupVersion)
if err != nil {
return fmt.Errorf("Extensions API version '%s' is not recognized (valid values: %s)",
config.GroupVersion, g.GroupVersions)
}
config.Codec = versionInterfaces.Codec
if config.QPS == 0 { if config.QPS == 0 {
config.QPS = 5 config.QPS = 5
} }
......
...@@ -17,7 +17,7 @@ limitations under the License. ...@@ -17,7 +17,7 @@ limitations under the License.
package unversioned package unversioned
import ( import (
"fmt" api "k8s.io/kubernetes/pkg/api"
registered "k8s.io/kubernetes/pkg/apimachinery/registered" registered "k8s.io/kubernetes/pkg/apimachinery/registered"
unversioned "k8s.io/kubernetes/pkg/client/unversioned" unversioned "k8s.io/kubernetes/pkg/client/unversioned"
) )
...@@ -149,12 +149,7 @@ func setConfigDefaults(config *unversioned.Config) error { ...@@ -149,12 +149,7 @@ func setConfigDefaults(config *unversioned.Config) error {
config.GroupVersion = &copyGroupVersion config.GroupVersion = &copyGroupVersion
//} //}
versionInterfaces, err := g.InterfacesFor(*config.GroupVersion) config.Codec = api.Codecs.LegacyCodec(*config.GroupVersion)
if err != nil {
return fmt.Errorf("Legacy API version '%s' is not recognized (valid values: %s)",
config.GroupVersion, g.GroupVersions)
}
config.Codec = versionInterfaces.Codec
if config.QPS == 0 { if config.QPS == 0 {
config.QPS = 5 config.QPS = 5
} }
......
...@@ -75,7 +75,7 @@ func TestGetServerGroupsWithV1Server(t *testing.T) { ...@@ -75,7 +75,7 @@ func TestGetServerGroupsWithV1Server(t *testing.T) {
} }
output, err := json.Marshal(obj) output, err := json.Marshal(obj)
if err != nil { if err != nil {
t.Errorf("unexpected encoding error: %v", err) t.Fatalf("unexpected encoding error: %v", err)
return return
} }
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
...@@ -88,7 +88,7 @@ func TestGetServerGroupsWithV1Server(t *testing.T) { ...@@ -88,7 +88,7 @@ func TestGetServerGroupsWithV1Server(t *testing.T) {
// ServerGroups should not return an error even if server returns error at /api and /apis // ServerGroups should not return an error even if server returns error at /api and /apis
apiGroupList, err := client.Discovery().ServerGroups() apiGroupList, err := client.Discovery().ServerGroups()
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
groupVersions := ExtractGroupVersions(apiGroupList) groupVersions := ExtractGroupVersions(apiGroupList)
if !reflect.DeepEqual(groupVersions, []string{"v1"}) { if !reflect.DeepEqual(groupVersions, []string{"v1"}) {
......
...@@ -18,8 +18,11 @@ package latest ...@@ -18,8 +18,11 @@ package latest
import ( import (
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
_ "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/v1"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime/serializer/json"
"k8s.io/kubernetes/pkg/runtime/serializer/versioning"
) )
// Version is the string that represents the current external default version. // Version is the string that represents the current external default version.
...@@ -37,8 +40,9 @@ const OldestVersion = "v1" ...@@ -37,8 +40,9 @@ const OldestVersion = "v1"
// with a set of versions to choose. // with a set of versions to choose.
var Versions = []string{"v1"} var Versions = []string{"v1"}
// Codec is the default codec for serializing output that should use var Codec = versioning.NewCodecForScheme(
// the latest supported version. Use this Codec when writing to api.Scheme,
// disk, a data store that is not dynamically versioned, or in tests. json.NewYAMLSerializer(json.DefaultMetaFactory, api.Scheme, runtime.ObjectTyperToTyper(api.Scheme)),
// This codec can decode any object that Kubernetes is aware of. []unversioned.GroupVersion{{Version: Version}},
var Codec = runtime.YAMLDecoder(v1.Codec) []unversioned.GroupVersion{{Version: runtime.APIVersionInternal}},
)
...@@ -26,7 +26,7 @@ var Scheme = runtime.NewScheme() ...@@ -26,7 +26,7 @@ var Scheme = runtime.NewScheme()
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
// TODO this should be in the "kubeconfig" group // TODO this should be in the "kubeconfig" group
var SchemeGroupVersion = unversioned.GroupVersion{Group: "", Version: ""} var SchemeGroupVersion = unversioned.GroupVersion{Group: "", Version: runtime.APIVersionInternal}
func init() { func init() {
Scheme.AddKnownTypes(SchemeGroupVersion, Scheme.AddKnownTypes(SchemeGroupVersion,
......
...@@ -42,14 +42,14 @@ type Config struct { ...@@ -42,14 +42,14 @@ type Config struct {
// CurrentContext is the name of the context that you would like to use by default // CurrentContext is the name of the context that you would like to use by default
CurrentContext string `json:"current-context"` CurrentContext string `json:"current-context"`
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
Extensions map[string]*runtime.EmbeddedObject `json:"extensions,omitempty"` Extensions map[string]runtime.Object `json:"extensions,omitempty"`
} }
// IMPORTANT if you add fields to this struct, please update IsConfigEmpty() // IMPORTANT if you add fields to this struct, please update IsConfigEmpty()
type Preferences struct { type Preferences struct {
Colors bool `json:"colors,omitempty"` Colors bool `json:"colors,omitempty"`
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
Extensions map[string]*runtime.EmbeddedObject `json:"extensions,omitempty"` Extensions map[string]runtime.Object `json:"extensions,omitempty"`
} }
// Cluster contains information about how to communicate with a kubernetes cluster // Cluster contains information about how to communicate with a kubernetes cluster
...@@ -67,7 +67,7 @@ type Cluster struct { ...@@ -67,7 +67,7 @@ type Cluster struct {
// CertificateAuthorityData contains PEM-encoded certificate authority certificates. Overrides CertificateAuthority // CertificateAuthorityData contains PEM-encoded certificate authority certificates. Overrides CertificateAuthority
CertificateAuthorityData []byte `json:"certificate-authority-data,omitempty"` CertificateAuthorityData []byte `json:"certificate-authority-data,omitempty"`
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
Extensions map[string]*runtime.EmbeddedObject `json:"extensions,omitempty"` Extensions map[string]runtime.Object `json:"extensions,omitempty"`
} }
// AuthInfo contains information that describes identity information. This is use to tell the kubernetes cluster who you are. // AuthInfo contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
...@@ -89,7 +89,7 @@ type AuthInfo struct { ...@@ -89,7 +89,7 @@ type AuthInfo struct {
// Password is the password for basic authentication to the kubernetes cluster. // Password is the password for basic authentication to the kubernetes cluster.
Password string `json:"password,omitempty"` Password string `json:"password,omitempty"`
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
Extensions map[string]*runtime.EmbeddedObject `json:"extensions,omitempty"` Extensions map[string]runtime.Object `json:"extensions,omitempty"`
} }
// Context is a tuple of references to a cluster (how do I communicate with a kubernetes cluster), a user (how do I identify myself), and a namespace (what subset of resources do I want to work with) // Context is a tuple of references to a cluster (how do I communicate with a kubernetes cluster), a user (how do I identify myself), and a namespace (what subset of resources do I want to work with)
...@@ -103,7 +103,7 @@ type Context struct { ...@@ -103,7 +103,7 @@ type Context struct {
// Namespace is the default namespace to use on unspecified requests // Namespace is the default namespace to use on unspecified requests
Namespace string `json:"namespace,omitempty"` Namespace string `json:"namespace,omitempty"`
// Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields // Extensions holds additional information. This is useful for extenders so that reads and writes don't clobber unknown fields
Extensions map[string]*runtime.EmbeddedObject `json:"extensions,omitempty"` Extensions map[string]runtime.Object `json:"extensions,omitempty"`
} }
// NewConfig is a convenience function that returns a new Config object with non-nil maps // NewConfig is a convenience function that returns a new Config object with non-nil maps
...@@ -113,26 +113,26 @@ func NewConfig() *Config { ...@@ -113,26 +113,26 @@ func NewConfig() *Config {
Clusters: make(map[string]*Cluster), Clusters: make(map[string]*Cluster),
AuthInfos: make(map[string]*AuthInfo), AuthInfos: make(map[string]*AuthInfo),
Contexts: make(map[string]*Context), Contexts: make(map[string]*Context),
Extensions: make(map[string]*runtime.EmbeddedObject), Extensions: make(map[string]runtime.Object),
} }
} }
// NewConfig is a convenience function that returns a new Config object with non-nil maps // NewConfig is a convenience function that returns a new Config object with non-nil maps
func NewContext() *Context { func NewContext() *Context {
return &Context{Extensions: make(map[string]*runtime.EmbeddedObject)} return &Context{Extensions: make(map[string]runtime.Object)}
} }
// NewConfig is a convenience function that returns a new Config object with non-nil maps // NewConfig is a convenience function that returns a new Config object with non-nil maps
func NewCluster() *Cluster { func NewCluster() *Cluster {
return &Cluster{Extensions: make(map[string]*runtime.EmbeddedObject)} return &Cluster{Extensions: make(map[string]runtime.Object)}
} }
// NewConfig is a convenience function that returns a new Config object with non-nil maps // NewConfig is a convenience function that returns a new Config object with non-nil maps
func NewAuthInfo() *AuthInfo { func NewAuthInfo() *AuthInfo {
return &AuthInfo{Extensions: make(map[string]*runtime.EmbeddedObject)} return &AuthInfo{Extensions: make(map[string]runtime.Object)}
} }
// NewConfig is a convenience function that returns a new Config object with non-nil maps // NewConfig is a convenience function that returns a new Config object with non-nil maps
func NewPreferences() *Preferences { func NewPreferences() *Preferences {
return &Preferences{Extensions: make(map[string]*runtime.EmbeddedObject)} return &Preferences{Extensions: make(map[string]runtime.Object)}
} }
...@@ -69,7 +69,7 @@ func init() { ...@@ -69,7 +69,7 @@ func init() {
if err := s.Convert(&in.Contexts, &out.Contexts, 0); err != nil { if err := s.Convert(&in.Contexts, &out.Contexts, 0); err != nil {
return err return err
} }
out.Extensions = make(map[string]*runtime.EmbeddedObject) out.Extensions = make(map[string]runtime.Object)
if err := s.Convert(&in.Extensions, &out.Extensions, 0); err != nil { if err := s.Convert(&in.Extensions, &out.Extensions, 0); err != nil {
return err return err
} }
...@@ -192,10 +192,10 @@ func init() { ...@@ -192,10 +192,10 @@ func init() {
return nil return nil
}, },
func(in *[]NamedExtension, out *map[string]*runtime.EmbeddedObject, s conversion.Scope) error { func(in *[]NamedExtension, out *map[string]runtime.Object, s conversion.Scope) error {
for _, curr := range *in { for _, curr := range *in {
newExtension := &runtime.EmbeddedObject{} var newExtension runtime.Object
if err := s.Convert(&curr.Extension, newExtension, 0); err != nil { if err := s.Convert(&curr.Extension, &newExtension, 0); err != nil {
return err return err
} }
(*out)[curr.Name] = newExtension (*out)[curr.Name] = newExtension
...@@ -203,7 +203,7 @@ func init() { ...@@ -203,7 +203,7 @@ func init() {
return nil return nil
}, },
func(in *map[string]*runtime.EmbeddedObject, out *[]NamedExtension, s conversion.Scope) error { func(in *map[string]runtime.Object, out *[]NamedExtension, s conversion.Scope) error {
allKeys := make([]string, 0, len(*in)) allKeys := make([]string, 0, len(*in))
for key := range *in { for key := range *in {
allKeys = append(allKeys, key) allKeys = append(allKeys, key)
......
...@@ -19,16 +19,12 @@ package v1 ...@@ -19,16 +19,12 @@ package v1
import ( import (
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
"k8s.io/kubernetes/pkg/runtime"
) )
// SchemeGroupVersion is group version used to register these objects // SchemeGroupVersion is group version used to register these objects
// TODO this should be in the "kubeconfig" group // TODO this should be in the "kubeconfig" group
var SchemeGroupVersion = unversioned.GroupVersion{Group: "", Version: "v1"} var SchemeGroupVersion = unversioned.GroupVersion{Group: "", Version: "v1"}
// Codec encodes internal objects to the v1 scheme
var Codec = runtime.CodecFor(api.Scheme, SchemeGroupVersion)
func init() { func init() {
api.Scheme.AddKnownTypes(SchemeGroupVersion, api.Scheme.AddKnownTypes(SchemeGroupVersion,
&Config{}, &Config{},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment