From a87d927588e5fb391ce71f79e97648ba4452bdc4 Mon Sep 17 00:00:00 2001 From: deads2k Date: Fri, 13 Nov 2015 16:20:54 -0500 Subject: [PATCH] update client.Config to use GroupVersion --- cluster/addons/dns/kube2sky/kube2sky.go | 7 +- cmd/integration/integration.go | 8 +- cmd/kube-apiserver/app/server.go | 12 +- contrib/mesos/pkg/executor/executor_test.go | 8 +- .../scheduler/integration/integration_test.go | 4 +- pkg/api/testapi/testapi.go | 9 ++ pkg/client/cache/listwatch_test.go | 4 +- pkg/client/unversioned/client_test.go | 17 +-- .../unversioned/clientcmd/client_config.go | 9 +- .../clientcmd/client_config_test.go | 4 +- pkg/client/unversioned/discovery_client.go | 2 +- pkg/client/unversioned/extensions.go | 12 +- pkg/client/unversioned/helper.go | 104 +++++++++++------- .../unversioned/helper_blackbox_test.go | 57 +++++----- pkg/client/unversioned/helper_test.go | 14 +-- pkg/client/unversioned/request_test.go | 2 +- pkg/client/unversioned/restclient_test.go | 52 ++++----- pkg/controller/controller_utils_test.go | 2 +- pkg/controller/daemon/controller_test.go | 2 +- .../endpoint/endpoints_controller_test.go | 24 ++-- pkg/controller/job/controller_test.go | 10 +- .../replication_controller_test.go | 28 ++--- pkg/kubectl/cmd/annotate_test.go | 8 +- pkg/kubectl/cmd/attach_test.go | 5 +- pkg/kubectl/cmd/clusterinfo.go | 7 +- pkg/kubectl/cmd/edit.go | 2 +- pkg/kubectl/cmd/exec_test.go | 3 +- pkg/kubectl/cmd/get.go | 3 +- pkg/kubectl/cmd/get_test.go | 8 +- pkg/kubectl/cmd/label_test.go | 6 +- pkg/kubectl/cmd/log_test.go | 3 +- pkg/kubectl/cmd/portforward_test.go | 5 +- pkg/kubectl/cmd/run_test.go | 2 +- pkg/kubectl/cmd/util/clientcache.go | 28 ++++- pkg/kubectl/cmd/util/factory.go | 10 +- pkg/kubectl/cmd/util/printing.go | 11 ++ pkg/kubectl/rolling_updater_test.go | 4 +- plugin/pkg/scheduler/factory/factory_test.go | 10 +- test/integration/client_test.go | 6 +- test/integration/framework/master_utils.go | 2 +- test/integration/metrics_test.go | 2 +- test/integration/persistent_volumes_test.go | 6 +- test/integration/scheduler_test.go | 10 +- test/integration/secret_test.go | 2 +- test/integration/service_account_test.go | 4 +- 45 files changed, 314 insertions(+), 224 deletions(-) diff --git a/cluster/addons/dns/kube2sky/kube2sky.go b/cluster/addons/dns/kube2sky/kube2sky.go index 958b80fd761..2ebfe96c8c0 100644 --- a/cluster/addons/dns/kube2sky/kube2sky.go +++ b/cluster/addons/dns/kube2sky/kube2sky.go @@ -35,6 +35,7 @@ import ( "github.com/golang/glog" skymsg "github.com/skynetservices/skydns/msg" kapi "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" kcache "k8s.io/kubernetes/pkg/client/cache" kclient "k8s.io/kubernetes/pkg/client/unversioned" kclientcmd "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" @@ -479,8 +480,8 @@ func newKubeClient() (*kclient.Client, error) { if masterURL != "" && *argKubecfgFile == "" { // Only --kube_master_url was provided. config = &kclient.Config{ - Host: masterURL, - Version: "v1", + Host: masterURL, + GroupVersion: &unversioned.GroupVersion{Version: "v1"}, } } else { // We either have: @@ -498,7 +499,7 @@ func newKubeClient() (*kclient.Client, error) { } glog.Infof("Using %s for kubernetes master", config.Host) - glog.Infof("Using kubernetes API %s", config.Version) + glog.Infof("Using kubernetes API %v", config.GroupVersion) return kclient.New(config) } diff --git a/cmd/integration/integration.go b/cmd/integration/integration.go index 7ffe633725c..f351d33d609 100644 --- a/cmd/integration/integration.go +++ b/cmd/integration/integration.go @@ -133,11 +133,11 @@ func startComponents(firstManifestURL, secondManifestURL string) (string, string glog.Fatalf("Failed to connect to etcd") } - cl := client.NewOrDie(&client.Config{Host: apiServer.URL, Version: testapi.Default.GroupAndVersion()}) + cl := client.NewOrDie(&client.Config{Host: apiServer.URL, GroupVersion: testapi.Default.GroupVersion()}) // TODO: caesarxuchao: hacky way to specify version of Experimental client. // We will fix this by supporting multiple group versions in Config - cl.ExtensionsClient = client.NewExtensionsOrDie(&client.Config{Host: apiServer.URL, Version: testapi.Extensions.GroupAndVersion()}) + cl.ExtensionsClient = client.NewExtensionsOrDie(&client.Config{Host: apiServer.URL, GroupVersion: testapi.Extensions.GroupVersion()}) storageVersions := make(map[string]string) etcdStorage, err := master.NewEtcdStorage(etcdClient, latest.GroupOrDie("").InterfacesFor, testapi.Default.GroupAndVersion(), etcdtest.PathPrefix()) @@ -987,10 +987,10 @@ func main() { // Wait for the synchronization threads to come up. time.Sleep(time.Second * 10) - kubeClient := client.NewOrDie(&client.Config{Host: apiServerURL, Version: testapi.Default.GroupAndVersion()}) + kubeClient := client.NewOrDie(&client.Config{Host: apiServerURL, GroupVersion: testapi.Default.GroupVersion()}) // TODO: caesarxuchao: hacky way to specify version of Experimental client. // We will fix this by supporting multiple group versions in Config - kubeClient.ExtensionsClient = client.NewExtensionsOrDie(&client.Config{Host: apiServerURL, Version: testapi.Extensions.GroupAndVersion()}) + kubeClient.ExtensionsClient = client.NewExtensionsOrDie(&client.Config{Host: apiServerURL, GroupVersion: testapi.Extensions.GroupVersion()}) // Run tests in parallel testFuncs := []testFunc{ diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index a1c0f88e7f9..006a5b9b4bf 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -36,6 +36,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" apiutil "k8s.io/kubernetes/pkg/api/util" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/apiserver" @@ -432,9 +433,16 @@ func (s *APIServer) Run(_ []string) error { } clientConfig := &client.Config{ - Host: net.JoinHostPort(s.InsecureBindAddress.String(), strconv.Itoa(s.InsecurePort)), - Version: s.DeprecatedStorageVersion, + Host: net.JoinHostPort(s.InsecureBindAddress.String(), strconv.Itoa(s.InsecurePort)), } + if len(s.DeprecatedStorageVersion) != 0 { + gv, err := unversioned.ParseGroupVersion(s.DeprecatedStorageVersion) + if err != nil { + glog.Fatalf("error in parsing group version: %s", err) + } + clientConfig.GroupVersion = &gv + } + client, err := client.New(clientConfig) if err != nil { glog.Fatalf("Invalid server address: %v", err) diff --git a/contrib/mesos/pkg/executor/executor_test.go b/contrib/mesos/pkg/executor/executor_test.go index 166b67235bb..8bcae119d54 100644 --- a/contrib/mesos/pkg/executor/executor_test.go +++ b/contrib/mesos/pkg/executor/executor_test.go @@ -137,8 +137,8 @@ func TestExecutorLaunchAndKillTask(t *testing.T) { Updates: updates, NodeInfos: make(chan NodeInfo, 1), APIClient: client.NewOrDie(&client.Config{ - Host: testApiServer.server.URL, - Version: testapi.Default.Version(), + Host: testApiServer.server.URL, + GroupVersion: testapi.Default.GroupVersion(), }), PodStatusFunc: func(pod *api.Pod) (*api.PodStatus, error) { return &api.PodStatus{ @@ -338,8 +338,8 @@ func TestExecutorFrameworkMessage(t *testing.T) { Updates: make(chan kubetypes.PodUpdate, 1024), NodeInfos: make(chan NodeInfo, 1), APIClient: client.NewOrDie(&client.Config{ - Host: testApiServer.server.URL, - Version: testapi.Default.Version(), + Host: testApiServer.server.URL, + GroupVersion: testapi.Default.GroupVersion(), }), PodStatusFunc: func(pod *api.Pod) (*api.PodStatus, error) { return &api.PodStatus{ diff --git a/contrib/mesos/pkg/scheduler/integration/integration_test.go b/contrib/mesos/pkg/scheduler/integration/integration_test.go index 822c7ac86f8..2641fe7f91d 100644 --- a/contrib/mesos/pkg/scheduler/integration/integration_test.go +++ b/contrib/mesos/pkg/scheduler/integration/integration_test.go @@ -453,8 +453,8 @@ func newLifecycleTest(t *testing.T) lifecycleTest { // create framework client := client.NewOrDie(&client.Config{ - Host: apiServer.server.URL, - Version: testapi.Default.Version(), + Host: apiServer.server.URL, + GroupVersion: testapi.Default.GroupVersion(), }) c := *schedcfg.CreateDefaultConfig() fw := framework.New(framework.Config{ diff --git a/pkg/api/testapi/testapi.go b/pkg/api/testapi/testapi.go index 7dbc25637a1..970ae920e6e 100644 --- a/pkg/api/testapi/testapi.go +++ b/pkg/api/testapi/testapi.go @@ -24,6 +24,7 @@ import ( "k8s.io/kubernetes/pkg/api" _ "k8s.io/kubernetes/pkg/api/install" + "k8s.io/kubernetes/pkg/api/unversioned" _ "k8s.io/kubernetes/pkg/apis/extensions/install" _ "k8s.io/kubernetes/pkg/apis/metrics/install" @@ -87,6 +88,14 @@ func (g TestGroup) GroupAndVersion() string { return g.GroupVersionUnderTest } +func (g TestGroup) GroupVersion() *unversioned.GroupVersion { + gv, err := unversioned.ParseGroupVersion(g.GroupVersionUnderTest) + if err != nil { + panic(err) + } + return &gv +} + // Codec returns the codec for the API version to test against, as set by the // KUBE_TEST_API env var. func (g TestGroup) Codec() runtime.Codec { diff --git a/pkg/client/cache/listwatch_test.go b/pkg/client/cache/listwatch_test.go index 27b4eb0803c..39d9c7d6fbf 100644 --- a/pkg/client/cache/listwatch_test.go +++ b/pkg/client/cache/listwatch_test.go @@ -96,7 +96,7 @@ func TestListWatchesCanList(t *testing.T) { } server := httptest.NewServer(&handler) defer server.Close() - client := client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: server.URL, GroupVersion: testapi.Default.GroupVersion()}) lw := NewListWatchFromClient(client, item.resource, item.namespace, item.fieldSelector) // This test merely tests that the correct request is made. lw.List() @@ -162,7 +162,7 @@ func TestListWatchesCanWatch(t *testing.T) { } server := httptest.NewServer(&handler) defer server.Close() - client := client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: server.URL, GroupVersion: testapi.Default.GroupVersion()}) lw := NewListWatchFromClient(client, item.resource, item.namespace, item.fieldSelector) // This test merely tests that the correct request is made. lw.Watch(api.ListOptions{ResourceVersion: item.rv}) diff --git a/pkg/client/unversioned/client_test.go b/pkg/client/unversioned/client_test.go index 640a24d3a4b..95ac1a6e3da 100644 --- a/pkg/client/unversioned/client_test.go +++ b/pkg/client/unversioned/client_test.go @@ -61,7 +61,6 @@ type testClient struct { Response Response Error bool Created bool - Version string server *httptest.Server handler *util.FakeHandler // For query args, an optional function to validate the contents @@ -80,24 +79,16 @@ func (c *testClient) Setup(t *testing.T) *testClient { } c.server = httptest.NewServer(c.handler) if c.Client == nil { - version := c.Version - if len(version) == 0 { - version = testapi.Default.Version() - } c.Client = NewOrDie(&Config{ - Host: c.server.URL, - Version: version, + Host: c.server.URL, + GroupVersion: testapi.Default.GroupVersion(), }) // TODO: caesarxuchao: hacky way to specify version of Experimental client. // We will fix this by supporting multiple group versions in Config - version = c.Version - if len(version) == 0 { - version = testapi.Extensions.Version() - } c.ExtensionsClient = NewExtensionsOrDie(&Config{ - Host: c.server.URL, - Version: version, + Host: c.server.URL, + GroupVersion: testapi.Extensions.GroupVersion(), }) } c.QueryValidator = map[string]func(string, string) bool{} diff --git a/pkg/client/unversioned/clientcmd/client_config.go b/pkg/client/unversioned/clientcmd/client_config.go index 45b82b10958..9a58b9f98bd 100644 --- a/pkg/client/unversioned/clientcmd/client_config.go +++ b/pkg/client/unversioned/clientcmd/client_config.go @@ -26,6 +26,7 @@ import ( "github.com/imdario/mergo" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" clientauth "k8s.io/kubernetes/pkg/client/unversioned/auth" clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" @@ -99,7 +100,13 @@ func (config DirectClientConfig) ClientConfig() (*client.Config, error) { u.Fragment = "" clientConfig.Host = u.String() } - clientConfig.Version = configClusterInfo.APIVersion + if len(configClusterInfo.APIVersion) != 0 { + gv, err := unversioned.ParseGroupVersion(configClusterInfo.APIVersion) + if err != nil { + return nil, err + } + clientConfig.GroupVersion = &gv + } // only try to read the auth information if we are secure if client.IsConfigTransportTLS(*clientConfig) { diff --git a/pkg/client/unversioned/clientcmd/client_config_test.go b/pkg/client/unversioned/clientcmd/client_config_test.go index cb6f861d1cd..7cc2766f91a 100644 --- a/pkg/client/unversioned/clientcmd/client_config_test.go +++ b/pkg/client/unversioned/clientcmd/client_config_test.go @@ -157,7 +157,7 @@ func TestCreateClean(t *testing.T) { matchStringArg(config.Clusters["clean"].Server, clientConfig.Host, t) matchStringArg("", clientConfig.Prefix, t) - matchStringArg(config.Clusters["clean"].APIVersion, clientConfig.Version, t) + matchStringArg(config.Clusters["clean"].APIVersion, clientConfig.GroupVersion.String(), t) matchBoolArg(config.Clusters["clean"].InsecureSkipTLSVerify, clientConfig.Insecure, t) matchStringArg(config.AuthInfos["clean"].Token, clientConfig.BearerToken, t) } @@ -212,7 +212,7 @@ func TestCreateCleanDefault(t *testing.T) { } matchStringArg(config.Clusters["clean"].Server, clientConfig.Host, t) - matchStringArg(config.Clusters["clean"].APIVersion, clientConfig.Version, t) + matchStringArg(config.Clusters["clean"].APIVersion, clientConfig.GroupVersion.String(), t) matchBoolArg(config.Clusters["clean"].InsecureSkipTLSVerify, clientConfig.Insecure, t) matchStringArg(config.AuthInfos["clean"].Token, clientConfig.BearerToken, t) } diff --git a/pkg/client/unversioned/discovery_client.go b/pkg/client/unversioned/discovery_client.go index a9c0ed263a6..3287fa24f0c 100644 --- a/pkg/client/unversioned/discovery_client.go +++ b/pkg/client/unversioned/discovery_client.go @@ -140,7 +140,7 @@ func (d *DiscoveryClient) ServerResources() (map[string]*unversioned.APIResource func setDiscoveryDefaults(config *Config) error { config.Prefix = "" - config.Version = "" + config.GroupVersion = nil // Discovery client deals with unversioned objects, so we use api.Codec. config.Codec = api.Codec return nil diff --git a/pkg/client/unversioned/extensions.go b/pkg/client/unversioned/extensions.go index b4b152c63e5..547a3a73797 100644 --- a/pkg/client/unversioned/extensions.go +++ b/pkg/client/unversioned/extensions.go @@ -140,13 +140,17 @@ func setExtensionsDefaults(config *Config) error { } // TODO: Unconditionally set the config.Version, until we fix the config. //if config.Version == "" { - config.Version = g.GroupVersion + gv, err := unversioned.ParseGroupVersion(g.GroupVersion) + if err != nil { + return err + } + config.GroupVersion = &gv //} - versionInterfaces, err := g.InterfacesFor(config.Version) + versionInterfaces, err := g.InterfacesFor(config.GroupVersion.String()) if err != nil { - return fmt.Errorf("Extensions API version '%s' is not recognized (valid values: %s)", - config.Version, strings.Join(latest.GroupOrDie("extensions").Versions, ", ")) + return fmt.Errorf("Extensions API group/version '%v' is not recognized (valid values: %s)", + config.GroupVersion, strings.Join(latest.GroupOrDie("extensions").Versions, ", ")) } config.Codec = versionInterfaces.Codec if config.QPS == 0 { diff --git a/pkg/client/unversioned/helper.go b/pkg/client/unversioned/helper.go index b22f722b1d9..deb67f5a386 100644 --- a/pkg/client/unversioned/helper.go +++ b/pkg/client/unversioned/helper.go @@ -48,10 +48,10 @@ type Config struct { // Prefix is the sub path of the server. If not specified, the client will set // a default value. Use "/" to indicate the server root should be used Prefix string - // Version is the API version to talk to. Must be provided when initializing + // GroupVersion is the API version to talk to. Must be provided when initializing // a RESTClient directly. When initializing a Client, will be set with the default // code version. - Version string + GroupVersion *unversioned.GroupVersion // Codec specifies the encoding and decoding behavior for runtime.Objects passed // to a RESTClient or Client. Required when initializing a RESTClient, optional // when initializing a Client. @@ -208,7 +208,7 @@ func ServerAPIVersions(c *Config) (groupVersions []string, err error) { client := http.Client{Transport: transport} configCopy := *c - configCopy.Version = "" + configCopy.GroupVersion = nil configCopy.Prefix = "" baseURL, err := defaultServerUrlFor(c) if err != nil { @@ -254,50 +254,59 @@ func ServerAPIVersions(c *Config) (groupVersions []string, err error) { // stderr and try client's registered versions in order of preference. // - If version is config default, and the server does not support it, // return an error. -func NegotiateVersion(client *Client, c *Config, version string, clientRegisteredVersions []string) (string, error) { +func NegotiateVersion(client *Client, c *Config, requestedGV *unversioned.GroupVersion, clientRegisteredGVs []unversioned.GroupVersion) (*unversioned.GroupVersion, error) { var err error if client == nil { client, err = New(c) if err != nil { - return "", err + return nil, err } } clientVersions := sets.String{} - for _, v := range clientRegisteredVersions { - clientVersions.Insert(v) + for _, gv := range clientRegisteredGVs { + clientVersions.Insert(gv.String()) } apiVersions, err := client.ServerAPIVersions() if err != nil { // This is almost always a connection error, and higher level code should treat this as a generic error, // not a negotiation specific error. - return "", err + return nil, err } serverVersions := sets.String{} for _, v := range apiVersions.Versions { serverVersions.Insert(v) } + // If no version requested, use config version (may also be empty). - if len(version) == 0 { - version = c.Version + // make a copy of the original so we don't risk mutating input here or in the returned value + var preferredGV *unversioned.GroupVersion + switch { + case requestedGV != nil: + t := *requestedGV + preferredGV = &t + case c.GroupVersion != nil: + t := *c.GroupVersion + preferredGV = &t } + // If version explicitly requested verify that both client and server support it. // If server does not support warn, but try to negotiate a lower version. - if len(version) != 0 { - if !clientVersions.Has(version) { - return "", fmt.Errorf("client does not support API version %q; client supported API versions: %v", version, clientVersions) + if preferredGV != nil { + if !clientVersions.Has(preferredGV.String()) { + return nil, fmt.Errorf("client does not support API version %q; client supported API versions: %v", preferredGV, clientVersions) } - if serverVersions.Has(version) { - return version, nil + if serverVersions.Has(preferredGV.String()) { + return preferredGV, nil } // If we are using an explicit config version the server does not support, fail. - if version == c.Version { - return "", fmt.Errorf("server does not support API version %q", version) + if (c.GroupVersion != nil) && (*preferredGV == *c.GroupVersion) { + return nil, fmt.Errorf("server does not support API version %q", preferredGV) } } - for _, clientVersion := range clientRegisteredVersions { - if serverVersions.Has(clientVersion) { + for _, clientGV := range clientRegisteredGVs { + if serverVersions.Has(clientGV.String()) { // Version was not explicitly requested in command config (--api-version). // Ok to fall back to a supported version with a warning. // TODO: caesarxuchao: enable the warning message when we have @@ -305,11 +314,12 @@ func NegotiateVersion(client *Client, c *Config, version string, clientRegistere // if len(version) != 0 { // glog.Warningf("Server does not support API version '%s'. Falling back to '%s'.", version, clientVersion) // } - return clientVersion, nil + t := clientGV + return &t, nil } } - return "", fmt.Errorf("failed to negotiate an api version; server supports: %v, client supports: %v", - serverVersions, clientRegisteredVersions) + return nil, fmt.Errorf("failed to negotiate an api version; server supports: %v, client supports: %v", + serverVersions, clientVersions) } // NewOrDie creates a Kubernetes client and panics if the provided API version is not recognized. @@ -370,13 +380,12 @@ func SetKubernetesDefaults(config *Config) error { if len(config.UserAgent) == 0 { config.UserAgent = DefaultKubernetesUserAgent() } - if len(config.Version) == 0 { - config.Version = defaultVersionFor(config) + if config.GroupVersion == nil { + config.GroupVersion = defaultVersionFor(config) } - version := config.Version - versionInterfaces, err := latest.GroupOrDie("").InterfacesFor(version) + versionInterfaces, err := latest.GroupOrDie("").InterfacesFor(config.GroupVersion.String()) if err != nil { - return fmt.Errorf("API version '%s' is not recognized (valid values: %s)", version, strings.Join(latest.GroupOrDie("").Versions, ", ")) + return fmt.Errorf("API version '%v' is not recognized (valid values: %s)", *config.GroupVersion, strings.Join(latest.GroupOrDie("").Versions, ", ")) } if config.Codec == nil { config.Codec = versionInterfaces.Codec @@ -395,8 +404,8 @@ func SetKubernetesDefaults(config *Config) error { // A RESTClient created by this method is generic - it expects to operate on an API that follows // the Kubernetes conventions, but may not be the Kubernetes API. func RESTClientFor(config *Config) (*RESTClient, error) { - if len(config.Version) == 0 { - return nil, fmt.Errorf("version is required when initializing a RESTClient") + if config.GroupVersion == nil { + return nil, fmt.Errorf("GroupVersion is required when initializing a RESTClient") } if config.Codec == nil { return nil, fmt.Errorf("Codec is required when initializing a RESTClient") @@ -407,7 +416,7 @@ func RESTClientFor(config *Config) (*RESTClient, error) { return nil, err } - client := NewRESTClient(baseURL, config.Version, config.Codec, config.QPS, config.Burst) + client := NewRESTClient(baseURL, config.GroupVersion.String(), config.Codec, config.QPS, config.Burst) transport, err := TransportFor(config) if err != nil { @@ -432,7 +441,7 @@ func UnversionedRESTClientFor(config *Config) (*RESTClient, error) { return nil, err } - client := NewRESTClient(baseURL, config.Version, config.Codec, config.QPS, config.Burst) + client := NewRESTClient(baseURL, "", config.Codec, config.QPS, config.Burst) transport, err := TransportFor(config) if err != nil { @@ -448,7 +457,7 @@ func UnversionedRESTClientFor(config *Config) (*RESTClient, error) { // DefaultServerURL converts a host, host:port, or URL string to the default base server API path // to use with a Client at a given API version following the standard conventions for a // Kubernetes API. -func DefaultServerURL(host, prefix, version string, defaultTLS bool) (*url.URL, error) { +func DefaultServerURL(host, prefix string, groupVersion unversioned.GroupVersion, defaultTLS bool) (*url.URL, error) { if host == "" { return nil, fmt.Errorf("host must be a URL or a host:port pair") } @@ -481,7 +490,13 @@ func DefaultServerURL(host, prefix, version string, defaultTLS bool) (*url.URL, } // Add the version to the end of the path - hostURL.Path = path.Join(hostURL.Path, version) + if len(groupVersion.Group) > 0 { + hostURL.Path = path.Join(hostURL.Path, groupVersion.Group, groupVersion.Version) + + } else { + hostURL.Path = path.Join(hostURL.Path, groupVersion.Version) + + } return hostURL, nil } @@ -495,7 +510,7 @@ func DefaultServerURL(host, prefix, version string, defaultTLS bool) (*url.URL, func IsConfigTransportTLS(config Config) bool { // determination of TLS transport does not logically require a version to be specified // modify the copy of the config we got to satisfy preconditions for defaultServerUrlFor - config.Version = defaultVersionFor(&config) + config.GroupVersion = defaultVersionFor(&config) baseURL, err := defaultServerUrlFor(&config) if err != nil { @@ -516,18 +531,27 @@ func defaultServerUrlFor(config *Config) (*url.URL, error) { if host == "" { host = "localhost" } - return DefaultServerURL(host, config.Prefix, config.Version, defaultTLS) + + if config.GroupVersion != nil { + return DefaultServerURL(host, config.Prefix, *config.GroupVersion, defaultTLS) + } + return DefaultServerURL(host, config.Prefix, unversioned.GroupVersion{}, defaultTLS) } // defaultVersionFor is shared between defaultServerUrlFor and RESTClientFor -func defaultVersionFor(config *Config) string { - version := config.Version - if version == "" { +func defaultVersionFor(config *Config) *unversioned.GroupVersion { + if config.GroupVersion == nil { // Clients default to the preferred code API version // TODO: implement version negotiation (highest version supported by server) - version = latest.GroupOrDie("").Version + // TODO this drops out when groupmeta is refactored + gv, err := unversioned.ParseGroupVersion(latest.GroupOrDie("").GroupVersion) + if err != nil { + panic(err) + } + return &gv } - return version + + return config.GroupVersion } // DefaultKubernetesUserAgent returns the default user agent that clients can use. diff --git a/pkg/client/unversioned/helper_blackbox_test.go b/pkg/client/unversioned/helper_blackbox_test.go index d449b46ece9..f87b90d0849 100644 --- a/pkg/client/unversioned/helper_blackbox_test.go +++ b/pkg/client/unversioned/helper_blackbox_test.go @@ -27,6 +27,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/api/testapi" + uapi "k8s.io/kubernetes/pkg/api/unversioned" unversionedapi "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/fake" @@ -42,50 +43,50 @@ func objBody(object interface{}) io.ReadCloser { func TestNegotiateVersion(t *testing.T) { tests := []struct { - name, version, expectedVersion string - serverVersions []string - clientVersions []string - config *unversioned.Config - expectErr func(err error) bool - sendErr error + name string + version *uapi.GroupVersion + expectedVersion *uapi.GroupVersion + serverVersions []string + clientVersions []uapi.GroupVersion + config *unversioned.Config + expectErr func(err error) bool + sendErr error }{ { name: "server supports client default", - version: "version1", + version: &uapi.GroupVersion{Version: "version1"}, config: &unversioned.Config{}, - serverVersions: []string{"version1", testapi.Default.Version()}, - clientVersions: []string{"version1", testapi.Default.Version()}, - expectedVersion: "version1", + serverVersions: []string{"/version1", testapi.Default.Version()}, + clientVersions: []uapi.GroupVersion{{Version: "version1"}, {Version: testapi.Default.Version()}}, + expectedVersion: &uapi.GroupVersion{Version: "version1"}, }, { name: "server falls back to client supported", - version: testapi.Default.Version(), + version: &uapi.GroupVersion{Version: testapi.Default.Version()}, config: &unversioned.Config{}, - serverVersions: []string{"version1"}, - clientVersions: []string{"version1", testapi.Default.Version()}, - expectedVersion: "version1", + serverVersions: []string{"/version1"}, + clientVersions: []uapi.GroupVersion{{Version: "version1"}, {Version: testapi.Default.Version()}}, + expectedVersion: &uapi.GroupVersion{Version: "version1"}, }, { name: "explicit version supported", - version: "", - config: &unversioned.Config{Version: testapi.Default.Version()}, - serverVersions: []string{"version1", testapi.Default.Version()}, - clientVersions: []string{"version1", testapi.Default.Version()}, - expectedVersion: testapi.Default.Version(), + config: &unversioned.Config{GroupVersion: testapi.Default.GroupVersion()}, + serverVersions: []string{"/version1", testapi.Default.Version()}, + clientVersions: []uapi.GroupVersion{{Version: "version1"}, {Version: testapi.Default.Version()}}, + expectedVersion: &uapi.GroupVersion{Version: testapi.Default.Version()}, }, { name: "explicit version not supported", - version: "", - config: &unversioned.Config{Version: testapi.Default.Version()}, - serverVersions: []string{"version1"}, - clientVersions: []string{"version1", testapi.Default.Version()}, + config: &unversioned.Config{GroupVersion: testapi.Default.GroupVersion()}, + serverVersions: []string{"/version1"}, + clientVersions: []uapi.GroupVersion{{Version: "version1"}, {Version: testapi.Default.Version()}}, expectErr: func(err error) bool { return strings.Contains(err.Error(), `server does not support API version "v1"`) }, }, { name: "connection refused error", - config: &unversioned.Config{Version: testapi.Default.Version()}, - serverVersions: []string{"version1"}, - clientVersions: []string{"version1", testapi.Default.Version()}, + config: &unversioned.Config{GroupVersion: testapi.Default.GroupVersion()}, + serverVersions: []string{"/version1"}, + clientVersions: []uapi.GroupVersion{{Version: "version1"}, {Version: testapi.Default.Version()}}, sendErr: errors.New("connection refused"), expectErr: func(err error) bool { return strings.Contains(err.Error(), "connection refused") }, }, @@ -118,8 +119,8 @@ func TestNegotiateVersion(t *testing.T) { } continue } - if response != test.expectedVersion { - t.Errorf("expected version %s, got %s.", test.expectedVersion, response) + if *response != *test.expectedVersion { + t.Errorf("%s: expected version %s, got %s.", test.name, test.expectedVersion, response) } } } diff --git a/pkg/client/unversioned/helper_test.go b/pkg/client/unversioned/helper_test.go index 86e21539b51..86bc2f5eef1 100644 --- a/pkg/client/unversioned/helper_test.go +++ b/pkg/client/unversioned/helper_test.go @@ -90,17 +90,17 @@ func TestSetKubernetesDefaults(t *testing.T) { { Config{}, Config{ - Prefix: "/api", - Version: testapi.Default.Version(), - Codec: testapi.Default.Codec(), - QPS: 5, - Burst: 10, + Prefix: "/api", + GroupVersion: testapi.Default.GroupVersion(), + Codec: testapi.Default.Codec(), + QPS: 5, + Burst: 10, }, false, }, { Config{ - Version: "not_an_api", + GroupVersion: &unversioned.GroupVersion{Group: "not.a.group", Version: "not_an_api"}, }, Config{}, true, @@ -183,7 +183,7 @@ func TestHelperGetServerAPIVersions(t *testing.T) { w.WriteHeader(http.StatusOK) w.Write(output) })) - got, err := ServerAPIVersions(&Config{Host: server.URL, Version: "invalid version", Codec: testapi.Default.Codec()}) + got, err := ServerAPIVersions(&Config{Host: server.URL, GroupVersion: &unversioned.GroupVersion{Group: "invalid version", Version: "one"}, Codec: testapi.Default.Codec()}) if err != nil { t.Fatalf("unexpected encoding error: %v", err) } diff --git a/pkg/client/unversioned/request_test.go b/pkg/client/unversioned/request_test.go index f6a12f20e11..3131ee78fb7 100644 --- a/pkg/client/unversioned/request_test.go +++ b/pkg/client/unversioned/request_test.go @@ -1210,5 +1210,5 @@ func testRESTClient(t testing.TB, srv *httptest.Server) *RESTClient { } } baseURL.Path = testapi.Default.ResourcePath("", "", "") - return NewRESTClient(baseURL, testapi.Default.Version(), testapi.Default.Codec(), 0, 0) + return NewRESTClient(baseURL, testapi.Default.GroupVersion().String(), testapi.Default.Codec(), 0, 0) } diff --git a/pkg/client/unversioned/restclient_test.go b/pkg/client/unversioned/restclient_test.go index 801485d9ba0..873168b8a4a 100644 --- a/pkg/client/unversioned/restclient_test.go +++ b/pkg/client/unversioned/restclient_test.go @@ -38,7 +38,7 @@ func TestSetsCodec(t *testing.T) { "invalidVersion": {true, "", nil}, } for version, expected := range testCases { - client, err := New(&Config{Host: "127.0.0.1", Version: version}) + client, err := New(&Config{Host: "127.0.0.1", GroupVersion: &unversioned.GroupVersion{Version: version}}) switch { case err == nil && expected.Err: t.Errorf("expected error but was nil") @@ -59,13 +59,13 @@ func TestSetsCodec(t *testing.T) { } func TestRESTClientRequires(t *testing.T) { - if _, err := RESTClientFor(&Config{Host: "127.0.0.1", Version: "", Codec: testapi.Default.Codec()}); err == nil { + if _, err := RESTClientFor(&Config{Host: "127.0.0.1", Codec: testapi.Default.Codec()}); err == nil { t.Errorf("unexpected non-error") } - if _, err := RESTClientFor(&Config{Host: "127.0.0.1", Version: testapi.Default.Version()}); err == nil { + if _, err := RESTClientFor(&Config{Host: "127.0.0.1", GroupVersion: testapi.Default.GroupVersion()}); err == nil { t.Errorf("unexpected non-error") } - if _, err := RESTClientFor(&Config{Host: "127.0.0.1", Version: testapi.Default.Version(), Codec: testapi.Default.Codec()}); err != nil { + if _, err := RESTClientFor(&Config{Host: "127.0.0.1", GroupVersion: testapi.Default.GroupVersion(), Codec: testapi.Default.Codec()}); err != nil { t.Errorf("unexpected error: %v", err) } } @@ -88,7 +88,7 @@ func TestValidatesHostParameter(t *testing.T) { {"host/server", "", "", true}, } for i, testCase := range testCases { - c, err := RESTClientFor(&Config{Host: testCase.Host, Prefix: testCase.Prefix, Version: testapi.Default.Version(), Codec: testapi.Default.Codec()}) + c, err := RESTClientFor(&Config{Host: testCase.Host, Prefix: testCase.Prefix, GroupVersion: testapi.Default.GroupVersion(), Codec: testapi.Default.Codec()}) switch { case err == nil && testCase.Err: t.Errorf("expected error but was nil") @@ -118,10 +118,10 @@ func TestDoRequestBearer(t *testing.T) { defer testServer.Close() request, _ := http.NewRequest("GET", testServer.URL, nil) c, err := RESTClientFor(&Config{ - Host: testServer.URL, - Version: testapi.Default.Version(), - Codec: testapi.Default.Codec(), - BearerToken: "test", + Host: testServer.URL, + GroupVersion: testapi.Default.GroupVersion(), + Codec: testapi.Default.Codec(), + BearerToken: "test", }) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -146,10 +146,10 @@ func TestDoRequestWithoutPassword(t *testing.T) { testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() c, err := RESTClientFor(&Config{ - Host: testServer.URL, - Version: testapi.Default.Version(), - Codec: testapi.Default.Codec(), - Username: "test", + Host: testServer.URL, + GroupVersion: testapi.Default.GroupVersion(), + Codec: testapi.Default.Codec(), + Username: "test", }) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -185,11 +185,11 @@ func TestDoRequestSuccess(t *testing.T) { testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() c, err := RESTClientFor(&Config{ - Host: testServer.URL, - Version: testapi.Default.Version(), - Codec: testapi.Default.Codec(), - Username: "user", - Password: "pass", + Host: testServer.URL, + GroupVersion: testapi.Default.GroupVersion(), + Codec: testapi.Default.Codec(), + Username: "user", + Password: "pass", }) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -228,9 +228,9 @@ func TestDoRequestFailed(t *testing.T) { testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() c, err := RESTClientFor(&Config{ - Host: testServer.URL, - Version: testapi.Default.Version(), - Codec: testapi.Default.Codec(), + Host: testServer.URL, + GroupVersion: testapi.Default.GroupVersion(), + Codec: testapi.Default.Codec(), }) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -260,11 +260,11 @@ func TestDoRequestCreated(t *testing.T) { testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() c, err := RESTClientFor(&Config{ - Host: testServer.URL, - Version: testapi.Default.Version(), - Codec: testapi.Default.Codec(), - Username: "user", - Password: "pass", + Host: testServer.URL, + GroupVersion: testapi.Default.GroupVersion(), + Codec: testapi.Default.Codec(), + Username: "user", + Password: "pass", }) if err != nil { t.Fatalf("unexpected error: %v", err) diff --git a/pkg/controller/controller_utils_test.go b/pkg/controller/controller_utils_test.go index c9c39c0b557..8e863590f58 100644 --- a/pkg/controller/controller_utils_test.go +++ b/pkg/controller/controller_utils_test.go @@ -190,7 +190,7 @@ func TestCreatePods(t *testing.T) { } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) podControl := RealPodControl{ KubeClient: client, diff --git a/pkg/controller/daemon/controller_test.go b/pkg/controller/daemon/controller_test.go index eb5647679a8..4b8ed2a6949 100644 --- a/pkg/controller/daemon/controller_test.go +++ b/pkg/controller/daemon/controller_test.go @@ -130,7 +130,7 @@ func addPods(podStore cache.Store, nodeName string, label map[string]string, num } func newTestController() (*DaemonSetsController, *controller.FakePodControl) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) manager := NewDaemonSetsController(client, controller.NoResyncPeriodFunc) manager.podStoreSynced = alwaysReady podControl := &controller.FakePodControl{} diff --git a/pkg/controller/endpoint/endpoints_controller_test.go b/pkg/controller/endpoint/endpoints_controller_test.go index dcaaf6ab5c3..21ccd937d69 100644 --- a/pkg/controller/endpoint/endpoints_controller_test.go +++ b/pkg/controller/endpoint/endpoints_controller_test.go @@ -189,7 +189,7 @@ func TestSyncEndpointsItemsPreserveNoSelector(t *testing.T) { }}, }}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: ns}, @@ -221,7 +221,7 @@ func TestCheckLeftoverEndpoints(t *testing.T) { }}, }}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) endpoints.checkLeftoverEndpoints() @@ -249,7 +249,7 @@ func TestSyncEndpointsProtocolTCP(t *testing.T) { }}, }}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: ns}, @@ -277,7 +277,7 @@ func TestSyncEndpointsProtocolUDP(t *testing.T) { }}, }}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: ns}, @@ -302,7 +302,7 @@ func TestSyncEndpointsItemsEmptySelectorSelectsAll(t *testing.T) { Subsets: []api.EndpointSubset{}, }}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) addPods(endpoints.podStore.Store, ns, 1, 1, 0) endpoints.serviceStore.Store.Add(&api.Service{ @@ -339,7 +339,7 @@ func TestSyncEndpointsItemsEmptySelectorSelectsAllNotReady(t *testing.T) { Subsets: []api.EndpointSubset{}, }}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) addPods(endpoints.podStore.Store, ns, 0, 1, 1) endpoints.serviceStore.Store.Add(&api.Service{ @@ -376,7 +376,7 @@ func TestSyncEndpointsItemsEmptySelectorSelectsAllMixed(t *testing.T) { Subsets: []api.EndpointSubset{}, }}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) addPods(endpoints.podStore.Store, ns, 1, 1, 1) endpoints.serviceStore.Store.Add(&api.Service{ @@ -417,7 +417,7 @@ func TestSyncEndpointsItemsPreexisting(t *testing.T) { }}, }}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) addPods(endpoints.podStore.Store, ns, 1, 1, 0) endpoints.serviceStore.Store.Add(&api.Service{ @@ -457,7 +457,7 @@ func TestSyncEndpointsItemsPreexistingIdentical(t *testing.T) { }}, }}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) addPods(endpoints.podStore.Store, api.NamespaceDefault, 1, 1, 0) endpoints.serviceStore.Store.Add(&api.Service{ @@ -476,7 +476,7 @@ func TestSyncEndpointsItems(t *testing.T) { testServer, endpointsHandler := makeTestServer(t, ns, serverResponse{http.StatusOK, &api.Endpoints{}}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) addPods(endpoints.podStore.Store, ns, 3, 2, 0) addPods(endpoints.podStore.Store, "blah", 5, 2, 0) // make sure these aren't found! @@ -518,7 +518,7 @@ func TestSyncEndpointsItemsWithLabels(t *testing.T) { testServer, endpointsHandler := makeTestServer(t, ns, serverResponse{http.StatusOK, &api.Endpoints{}}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) addPods(endpoints.podStore.Store, ns, 3, 2, 0) serviceLabels := map[string]string{"foo": "bar"} @@ -578,7 +578,7 @@ func TestSyncEndpointsItemsPreexistingLabelsChange(t *testing.T) { }}, }}) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) endpoints := NewEndpointController(client, controller.NoResyncPeriodFunc) addPods(endpoints.podStore.Store, ns, 1, 1, 0) serviceLabels := map[string]string{"baz": "blah"} diff --git a/pkg/controller/job/controller_test.go b/pkg/controller/job/controller_test.go index 4714f6eb5b6..64f987de879 100644 --- a/pkg/controller/job/controller_test.go +++ b/pkg/controller/job/controller_test.go @@ -162,7 +162,7 @@ func TestControllerSyncJob(t *testing.T) { for name, tc := range testCases { // job manager setup - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) manager := NewJobController(client, controller.NoResyncPeriodFunc) fakePodControl := controller.FakePodControl{Err: tc.podControllerError} manager.podControl = &fakePodControl @@ -226,7 +226,7 @@ func TestControllerSyncJob(t *testing.T) { } func TestSyncJobDeleted(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) manager := NewJobController(client, controller.NoResyncPeriodFunc) fakePodControl := controller.FakePodControl{} manager.podControl = &fakePodControl @@ -246,7 +246,7 @@ func TestSyncJobDeleted(t *testing.T) { } func TestSyncJobUpdateRequeue(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) manager := NewJobController(client, controller.NoResyncPeriodFunc) fakePodControl := controller.FakePodControl{} manager.podControl = &fakePodControl @@ -267,7 +267,7 @@ func TestSyncJobUpdateRequeue(t *testing.T) { } func TestJobPodLookup(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) manager := NewJobController(client, controller.NoResyncPeriodFunc) manager.podStoreSynced = alwaysReady testCases := []struct { @@ -357,7 +357,7 @@ func (fe FakeJobExpectations) SatisfiedExpectations(controllerKey string) bool { // TestSyncJobExpectations tests that a pod cannot sneak in between counting active pods // and checking expectations. func TestSyncJobExpectations(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.GroupAndVersion()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) manager := NewJobController(client, controller.NoResyncPeriodFunc) fakePodControl := controller.FakePodControl{} manager.podControl = &fakePodControl diff --git a/pkg/controller/replication/replication_controller_test.go b/pkg/controller/replication/replication_controller_test.go index 90fe706760e..cd8654ca7a4 100644 --- a/pkg/controller/replication/replication_controller_test.go +++ b/pkg/controller/replication/replication_controller_test.go @@ -129,7 +129,7 @@ type serverResponse struct { } func TestSyncReplicationControllerDoesNothing(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) fakePodControl := controller.FakePodControl{} manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady @@ -145,7 +145,7 @@ func TestSyncReplicationControllerDoesNothing(t *testing.T) { } func TestSyncReplicationControllerDeletes(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) fakePodControl := controller.FakePodControl{} manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady @@ -161,7 +161,7 @@ func TestSyncReplicationControllerDeletes(t *testing.T) { } func TestDeleteFinalStateUnknown(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) fakePodControl := controller.FakePodControl{} manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady @@ -194,7 +194,7 @@ func TestDeleteFinalStateUnknown(t *testing.T) { } func TestSyncReplicationControllerCreates(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady @@ -216,7 +216,7 @@ func TestStatusUpdatesWithoutReplicasChange(t *testing.T) { } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady @@ -258,7 +258,7 @@ func TestControllerUpdateReplicas(t *testing.T) { testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady @@ -296,7 +296,7 @@ func TestSyncReplicationControllerDormancy(t *testing.T) { } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) fakePodControl := controller.FakePodControl{} manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) @@ -345,7 +345,7 @@ func TestSyncReplicationControllerDormancy(t *testing.T) { } func TestPodControllerLookup(t *testing.T) { - manager := NewReplicationManager(client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}), controller.NoResyncPeriodFunc, BurstReplicas) + manager := NewReplicationManager(client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}), controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady testCases := []struct { inRCs []*api.ReplicationController @@ -556,7 +556,7 @@ func TestControllerUpdateRequeue(t *testing.T) { testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() - client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: testServer.URL, GroupVersion: testapi.Default.GroupVersion()}) manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, BurstReplicas) manager.podStoreSynced = alwaysReady @@ -636,7 +636,7 @@ func TestControllerUpdateStatusWithFailure(t *testing.T) { } func doTestControllerBurstReplicas(t *testing.T, burstReplicas, numReplicas int) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) fakePodControl := controller.FakePodControl{} manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, burstReplicas) manager.podStoreSynced = alwaysReady @@ -756,7 +756,7 @@ func (fe FakeRCExpectations) SatisfiedExpectations(controllerKey string) bool { // TestRCSyncExpectations tests that a pod cannot sneak in between counting active pods // and checking expectations. func TestRCSyncExpectations(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) fakePodControl := controller.FakePodControl{} manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, 2) manager.podStoreSynced = alwaysReady @@ -781,7 +781,7 @@ func TestRCSyncExpectations(t *testing.T) { } func TestDeleteControllerAndExpectations(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, 10) manager.podStoreSynced = alwaysReady @@ -823,7 +823,7 @@ func TestDeleteControllerAndExpectations(t *testing.T) { } func TestRCManagerNotReady(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) fakePodControl := controller.FakePodControl{} manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, 2) manager.podControl = &fakePodControl @@ -860,7 +860,7 @@ func shuffle(controllers []*api.ReplicationController) []*api.ReplicationControl } func TestOverlappingRCs(t *testing.T) { - client := client.NewOrDie(&client.Config{Host: "", Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: "", GroupVersion: testapi.Default.GroupVersion()}) for i := 0; i < 5; i++ { manager := NewReplicationManager(client, controller.NoResyncPeriodFunc, 10) diff --git a/pkg/kubectl/cmd/annotate_test.go b/pkg/kubectl/cmd/annotate_test.go index fdcf2a3d08d..e9fddc2dd7b 100644 --- a/pkg/kubectl/cmd/annotate_test.go +++ b/pkg/kubectl/cmd/annotate_test.go @@ -392,7 +392,7 @@ func TestAnnotateErrors(t *testing.T) { f, tf, _ := NewAPIFactory() tf.Printer = &testPrinter{} tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + tf.ClientConfig = &client.Config{GroupVersion: testapi.Default.GroupVersion()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdAnnotate(f, buf) @@ -448,7 +448,7 @@ func TestAnnotateObject(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + tf.ClientConfig = &client.Config{GroupVersion: testapi.Default.GroupVersion()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdAnnotate(f, buf) @@ -498,7 +498,7 @@ func TestAnnotateObjectFromFile(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + tf.ClientConfig = &client.Config{GroupVersion: testapi.Default.GroupVersion()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdAnnotate(f, buf) @@ -551,7 +551,7 @@ func TestAnnotateMultipleObjects(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + tf.ClientConfig = &client.Config{GroupVersion: testapi.Default.GroupVersion()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdAnnotate(f, buf) diff --git a/pkg/kubectl/cmd/attach_test.go b/pkg/kubectl/cmd/attach_test.go index 7870ef68f2f..abc22a73d77 100644 --- a/pkg/kubectl/cmd/attach_test.go +++ b/pkg/kubectl/cmd/attach_test.go @@ -29,6 +29,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/fake" ) @@ -149,7 +150,7 @@ func TestAttach(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: test.version} + tf.ClientConfig = &client.Config{GroupVersion: &unversioned.GroupVersion{Version: test.version}} bufOut := bytes.NewBuffer([]byte{}) bufErr := bytes.NewBuffer([]byte{}) bufIn := bytes.NewBuffer([]byte{}) @@ -226,7 +227,7 @@ func TestAttachWarnings(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: test.version} + tf.ClientConfig = &client.Config{GroupVersion: &unversioned.GroupVersion{Version: test.version}} bufOut := bytes.NewBuffer([]byte{}) bufErr := bytes.NewBuffer([]byte{}) bufIn := bytes.NewBuffer([]byte{}) diff --git a/pkg/kubectl/cmd/clusterinfo.go b/pkg/kubectl/cmd/clusterinfo.go index da2e582ef0b..a5adb2d33da 100644 --- a/pkg/kubectl/cmd/clusterinfo.go +++ b/pkg/kubectl/cmd/clusterinfo.go @@ -85,7 +85,12 @@ func RunClusterInfo(factory *cmdutil.Factory, out io.Writer, cmd *cobra.Command) link += "http://" + ip + ":" + strconv.Itoa(port.Port) + " " } } else { - link = client.Host + "/api/" + client.Version + "/proxy/namespaces/" + service.ObjectMeta.Namespace + "/services/" + service.ObjectMeta.Name + if len(client.GroupVersion.Group) == 0 { + link = client.Host + "/api/" + client.GroupVersion.Version + "/proxy/namespaces/" + service.ObjectMeta.Namespace + "/services/" + service.ObjectMeta.Name + } else { + link = client.Host + "/api/" + client.GroupVersion.Group + "/" + client.GroupVersion.Version + "/proxy/namespaces/" + service.ObjectMeta.Namespace + "/services/" + service.ObjectMeta.Name + + } } name := service.ObjectMeta.Labels["kubernetes.io/name"] if len(name) == 0 { diff --git a/pkg/kubectl/cmd/edit.go b/pkg/kubectl/cmd/edit.go index 840e9d4c229..9d4a575787b 100644 --- a/pkg/kubectl/cmd/edit.go +++ b/pkg/kubectl/cmd/edit.go @@ -149,7 +149,7 @@ func RunEdit(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin windowsLineEndings := cmdutil.GetFlagBool(cmd, "windows-line-endings") edit := editor.NewDefaultEditor() - defaultVersion := cmdutil.OutputVersion(cmd, clientConfig.Version) + defaultVersion := cmdutil.OutputVersionFromGroupVersion(cmd, clientConfig.GroupVersion) results := editResults{} for { objs, err := resource.AsVersionedObjects(infos, defaultVersion) diff --git a/pkg/kubectl/cmd/exec_test.go b/pkg/kubectl/cmd/exec_test.go index 6cb9bc1ea28..fb432f94ebd 100644 --- a/pkg/kubectl/cmd/exec_test.go +++ b/pkg/kubectl/cmd/exec_test.go @@ -29,6 +29,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/fake" ) @@ -195,7 +196,7 @@ func TestExec(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: test.version} + tf.ClientConfig = &client.Config{GroupVersion: &unversioned.GroupVersion{Version: test.version}} bufOut := bytes.NewBuffer([]byte{}) bufErr := bytes.NewBuffer([]byte{}) bufIn := bytes.NewBuffer([]byte{}) diff --git a/pkg/kubectl/cmd/get.go b/pkg/kubectl/cmd/get.go index 112bf945a2e..0bd4a95b367 100644 --- a/pkg/kubectl/cmd/get.go +++ b/pkg/kubectl/cmd/get.go @@ -199,7 +199,6 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string if err != nil { return err } - defaultVersion := clientConfig.Version singular := false r := b.Flatten().Do() @@ -210,7 +209,7 @@ func RunGet(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string // the outermost object will be converted to the output-version, but inner // objects can use their mappings - version := cmdutil.OutputVersion(cmd, defaultVersion) + version := cmdutil.OutputVersionFromGroupVersion(cmd, clientConfig.GroupVersion) obj, err := resource.AsVersionedObject(infos, !singular, version) if err != nil { return err diff --git a/pkg/kubectl/cmd/get_test.go b/pkg/kubectl/cmd/get_test.go index d2c659b3897..c3911214494 100644 --- a/pkg/kubectl/cmd/get_test.go +++ b/pkg/kubectl/cmd/get_test.go @@ -121,7 +121,7 @@ func TestGetUnknownSchemaObject(t *testing.T) { Resp: &http.Response{StatusCode: 200, Body: objBody(codec, &internalType{Name: "foo"})}, } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + tf.ClientConfig = &client.Config{GroupVersion: testapi.Default.GroupVersion()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdGet(f, buf) @@ -193,7 +193,7 @@ func TestGetUnknownSchemaObjectListGeneric(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + tf.ClientConfig = &client.Config{GroupVersion: testapi.Default.GroupVersion()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdGet(f, buf) cmd.SetOutput(buf) @@ -235,7 +235,7 @@ func TestGetSchemaObject(t *testing.T) { Resp: &http.Response{StatusCode: 200, Body: objBody(codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}})}, } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: "v1"} + tf.ClientConfig = &client.Config{GroupVersion: &unversioned.GroupVersion{Version: "v1"}} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdGet(f, buf) @@ -460,7 +460,7 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + tf.ClientConfig = &client.Config{GroupVersion: testapi.Default.GroupVersion()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdGet(f, buf) diff --git a/pkg/kubectl/cmd/label_test.go b/pkg/kubectl/cmd/label_test.go index 7a3f8db6224..ece2ae0b36b 100644 --- a/pkg/kubectl/cmd/label_test.go +++ b/pkg/kubectl/cmd/label_test.go @@ -301,7 +301,7 @@ func TestLabelErrors(t *testing.T) { f, tf, _ := NewAPIFactory() tf.Printer = &testPrinter{} tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + tf.ClientConfig = &client.Config{GroupVersion: testapi.Default.GroupVersion()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdLabel(f, buf) @@ -354,7 +354,7 @@ func TestLabelForResourceFromFile(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + tf.ClientConfig = &client.Config{GroupVersion: testapi.Default.GroupVersion()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdLabel(f, buf) @@ -403,7 +403,7 @@ func TestLabelMultipleObjects(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + tf.ClientConfig = &client.Config{GroupVersion: testapi.Default.GroupVersion()} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdLabel(f, buf) diff --git a/pkg/kubectl/cmd/log_test.go b/pkg/kubectl/cmd/log_test.go index 0227db11771..da0332da62a 100644 --- a/pkg/kubectl/cmd/log_test.go +++ b/pkg/kubectl/cmd/log_test.go @@ -27,6 +27,7 @@ import ( "github.com/spf13/cobra" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/fake" ) @@ -65,7 +66,7 @@ func TestLog(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: test.version} + tf.ClientConfig = &client.Config{GroupVersion: &unversioned.GroupVersion{Version: test.version}} buf := bytes.NewBuffer([]byte{}) cmd := NewCmdLog(f, buf) diff --git a/pkg/kubectl/cmd/portforward_test.go b/pkg/kubectl/cmd/portforward_test.go index 7d7d45d56a9..10b776779b4 100644 --- a/pkg/kubectl/cmd/portforward_test.go +++ b/pkg/kubectl/cmd/portforward_test.go @@ -26,6 +26,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/fake" ) @@ -83,7 +84,7 @@ func TestPortForward(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: test.version} + tf.ClientConfig = &client.Config{GroupVersion: &unversioned.GroupVersion{Version: test.version}} ff := &fakePortForwarder{} if test.pfErr { ff.pfErr = fmt.Errorf("pf error") @@ -153,7 +154,7 @@ func TestPortForwardWithPFlag(t *testing.T) { }), } tf.Namespace = "test" - tf.ClientConfig = &client.Config{Version: test.version} + tf.ClientConfig = &client.Config{GroupVersion: &unversioned.GroupVersion{Version: test.version}} ff := &fakePortForwarder{} if test.pfErr { ff.pfErr = fmt.Errorf("pf error") diff --git a/pkg/kubectl/cmd/run_test.go b/pkg/kubectl/cmd/run_test.go index 4fc94558901..e89dde518d8 100644 --- a/pkg/kubectl/cmd/run_test.go +++ b/pkg/kubectl/cmd/run_test.go @@ -263,7 +263,7 @@ func TestGenerateService(t *testing.T) { for _, test := range tests { sawPOST := false f, tf, codec := NewAPIFactory() - tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + tf.ClientConfig = &client.Config{GroupVersion: testapi.Default.GroupVersion()} tf.Client = &fake.RESTClient{ Codec: codec, Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) { diff --git a/pkg/kubectl/cmd/util/clientcache.go b/pkg/kubectl/cmd/util/clientcache.go index 926e6540f82..ed74b5ddb6a 100644 --- a/pkg/kubectl/cmd/util/clientcache.go +++ b/pkg/kubectl/cmd/util/clientcache.go @@ -18,6 +18,7 @@ package util import ( "k8s.io/kubernetes/pkg/api/registered" + "k8s.io/kubernetes/pkg/api/unversioned" client "k8s.io/kubernetes/pkg/client/unversioned" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" ) @@ -60,18 +61,37 @@ func (c *ClientCache) ClientConfigForVersion(version string) (*client.Config, er } // TODO: have a better config copy method config := *c.defaultConfig - negotiatedVersion, err := client.NegotiateVersion(c.defaultClient, &config, version, registered.RegisteredVersions) + + // TODO these fall out when we finish the refactor + var preferredGV *unversioned.GroupVersion + if len(version) > 0 { + gv, err := unversioned.ParseGroupVersion(version) + if err != nil { + return nil, err + } + preferredGV = &gv + } + registeredGVs := []unversioned.GroupVersion{} + for _, gvString := range registered.RegisteredVersions { + gv, err := unversioned.ParseGroupVersion(gvString) + if err != nil { + return nil, err + } + registeredGVs = append(registeredGVs, gv) + } + + negotiatedVersion, err := client.NegotiateVersion(c.defaultClient, &config, preferredGV, registeredGVs) if err != nil { return nil, err } - config.Version = negotiatedVersion + config.GroupVersion = negotiatedVersion client.SetKubernetesDefaults(&config) c.configs[version] = &config // `version` does not necessarily equal `config.Version`. However, we know that we call this method again with // `config.Version`, we should get the the config we've just built. configCopy := config - c.configs[config.Version] = &configCopy + c.configs[config.GroupVersion.String()] = &configCopy return &config, nil } @@ -91,6 +111,6 @@ func (c *ClientCache) ClientForVersion(version string) (*client.Client, error) { return nil, err } - c.clients[config.Version] = client + c.clients[config.GroupVersion.String()] = client return client, nil } diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 81711c48a65..b3be9dce4d2 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -133,7 +133,10 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { Object: func() (meta.RESTMapper, runtime.ObjectTyper) { cfg, err := clientConfig.ClientConfig() CheckErr(err) - cmdApiVersion := cfg.Version + cmdApiVersion := "" + if cfg.GroupVersion != nil { + cmdApiVersion = cfg.GroupVersion.String() + } return kubectl.OutputVersionMapper{RESTMapper: mapper, OutputVersion: cmdApiVersion}, api.Scheme }, @@ -577,7 +580,10 @@ func (f *Factory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMappin if err != nil { return nil, err } - defaultVersion := clientConfig.Version + defaultVersion := "" + if clientConfig.GroupVersion != nil { + defaultVersion = clientConfig.GroupVersion.String() + } version := OutputVersion(cmd, defaultVersion) if len(version) == 0 { diff --git a/pkg/kubectl/cmd/util/printing.go b/pkg/kubectl/cmd/util/printing.go index 3a4803d9cc2..78081d37ff4 100644 --- a/pkg/kubectl/cmd/util/printing.go +++ b/pkg/kubectl/cmd/util/printing.go @@ -22,6 +22,7 @@ import ( "strings" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/kubectl" "github.com/spf13/cobra" @@ -75,6 +76,7 @@ func ValidateOutputArgs(cmd *cobra.Command) error { } // OutputVersion returns the preferred output version for generic content (JSON, YAML, or templates) +// TODO, when this has no callers, replace it with OutputVersionFromGroupVersion. Also this shoudl return a GroupVersion func OutputVersion(cmd *cobra.Command, defaultVersion string) string { outputVersion := GetFlagString(cmd, "output-version") if len(outputVersion) == 0 { @@ -83,6 +85,15 @@ func OutputVersion(cmd *cobra.Command, defaultVersion string) string { return outputVersion } +// OutputVersionFromGroupVersion returns the preferred output version for generic content (JSON, YAML, or templates) +func OutputVersionFromGroupVersion(cmd *cobra.Command, defaultGV *unversioned.GroupVersion) string { + outputVersion := GetFlagString(cmd, "output-version") + if len(outputVersion) == 0 && defaultGV != nil { + outputVersion = defaultGV.String() + } + return outputVersion +} + // PrinterForCommand returns the default printer for this command. // Requires that printer flags have been added to cmd (see AddPrinterFlags). func PrinterForCommand(cmd *cobra.Command) (kubectl.ResourcePrinter, bool, error) { diff --git a/pkg/kubectl/rolling_updater_test.go b/pkg/kubectl/rolling_updater_test.go index bd15d682302..796f3877326 100644 --- a/pkg/kubectl/rolling_updater_test.go +++ b/pkg/kubectl/rolling_updater_test.go @@ -1076,7 +1076,7 @@ func TestUpdateWithRetries(t *testing.T) { } }), } - clientConfig := &client.Config{Version: testapi.Default.Version()} + clientConfig := &client.Config{GroupVersion: testapi.Default.GroupVersion()} client := client.NewOrDie(clientConfig) client.Client = fakeClient.Client @@ -1173,7 +1173,7 @@ func TestAddDeploymentHash(t *testing.T) { } }), } - clientConfig := &client.Config{Version: testapi.Default.Version()} + clientConfig := &client.Config{GroupVersion: testapi.Default.GroupVersion()} client := client.NewOrDie(clientConfig) client.Client = fakeClient.Client diff --git a/plugin/pkg/scheduler/factory/factory_test.go b/plugin/pkg/scheduler/factory/factory_test.go index 7a54f7a69f9..b996bb2ccbe 100644 --- a/plugin/pkg/scheduler/factory/factory_test.go +++ b/plugin/pkg/scheduler/factory/factory_test.go @@ -44,7 +44,7 @@ func TestCreate(t *testing.T) { } server := httptest.NewServer(&handler) defer server.Close() - client := client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: server.URL, GroupVersion: testapi.Default.GroupVersion()}) factory := NewConfigFactory(client, nil) factory.Create() } @@ -62,7 +62,7 @@ func TestCreateFromConfig(t *testing.T) { } server := httptest.NewServer(&handler) defer server.Close() - client := client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: server.URL, GroupVersion: testapi.Default.GroupVersion()}) factory := NewConfigFactory(client, nil) // Pre-register some predicate and priority functions @@ -104,7 +104,7 @@ func TestCreateFromEmptyConfig(t *testing.T) { } server := httptest.NewServer(&handler) defer server.Close() - client := client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: server.URL, GroupVersion: testapi.Default.GroupVersion()}) factory := NewConfigFactory(client, nil) configData = []byte(`{}`) @@ -148,7 +148,7 @@ func TestDefaultErrorFunc(t *testing.T) { mux.Handle(testapi.Default.ResourcePath("pods", "bar", "foo"), &handler) server := httptest.NewServer(mux) defer server.Close() - factory := NewConfigFactory(client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Default.Version()}), nil) + factory := NewConfigFactory(client.NewOrDie(&client.Config{Host: server.URL, GroupVersion: testapi.Default.GroupVersion()}), nil) queue := cache.NewFIFO(cache.MetaNamespaceKeyFunc) podBackoff := podBackoff{ perPodBackoff: map[types.NamespacedName]*backoffEntry{}, @@ -231,7 +231,7 @@ func TestBind(t *testing.T) { } server := httptest.NewServer(&handler) defer server.Close() - client := client.NewOrDie(&client.Config{Host: server.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: server.URL, GroupVersion: testapi.Default.GroupVersion()}) b := binder{client} if err := b.Bind(item.binding); err != nil { diff --git a/test/integration/client_test.go b/test/integration/client_test.go index ebff71726a9..d0ea8169529 100644 --- a/test/integration/client_test.go +++ b/test/integration/client_test.go @@ -44,7 +44,7 @@ func TestClient(t *testing.T) { ns := api.NamespaceDefault framework.DeleteAllEtcdKeys() - client := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: s.URL, GroupVersion: testapi.Default.GroupVersion()}) info, err := client.ServerVersion() if err != nil { @@ -114,7 +114,7 @@ func TestSingleWatch(t *testing.T) { ns := "blargh" deleteAllEtcdKeys() - client := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: s.URL, GroupVersion: testapi.Default.GroupVersion()}) mkEvent := func(i int) *api.Event { name := fmt.Sprintf("event-%v", i) @@ -198,7 +198,7 @@ func TestMultiWatch(t *testing.T) { defer s.Close() ns := api.NamespaceDefault - client := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: s.URL, GroupVersion: testapi.Default.GroupVersion()}) dummyEvent := func(i int) *api.Event { name := fmt.Sprintf("unrelated-%v", i) diff --git a/test/integration/framework/master_utils.go b/test/integration/framework/master_utils.go index 21e0772a9a3..6eda513d308 100644 --- a/test/integration/framework/master_utils.go +++ b/test/integration/framework/master_utils.go @@ -96,7 +96,7 @@ func NewMasterComponents(c *Config) *MasterComponents { if c.DeleteEtcdKeys { DeleteAllEtcdKeys() } - restClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version(), QPS: c.QPS, Burst: c.Burst}) + restClient := client.NewOrDie(&client.Config{Host: s.URL, GroupVersion: testapi.Default.GroupVersion(), QPS: c.QPS, Burst: c.Burst}) rcStopCh := make(chan struct{}) controllerManager := replicationcontroller.NewReplicationManager(restClient, controller.NoResyncPeriodFunc, c.Burst) diff --git a/test/integration/metrics_test.go b/test/integration/metrics_test.go index b974539464a..c3d2d0be34c 100644 --- a/test/integration/metrics_test.go +++ b/test/integration/metrics_test.go @@ -109,7 +109,7 @@ func TestApiserverMetrics(t *testing.T) { // Make a request to the apiserver to ensure there's at least one data point // for the metrics we're expecting -- otherwise, they won't be exported. - client := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: s.URL, GroupVersion: testapi.Default.GroupVersion()}) if _, err := client.Pods(api.NamespaceDefault).List(labels.Everything(), fields.Everything()); err != nil { t.Fatalf("unexpected error getting pods: %v", err) } diff --git a/test/integration/persistent_volumes_test.go b/test/integration/persistent_volumes_test.go index 44453a6965a..6bf3f62dcf1 100644 --- a/test/integration/persistent_volumes_test.go +++ b/test/integration/persistent_volumes_test.go @@ -43,9 +43,9 @@ func TestPersistentVolumeRecycler(t *testing.T) { defer s.Close() deleteAllEtcdKeys() - binderClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) - recyclerClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) - testClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) + binderClient := client.NewOrDie(&client.Config{Host: s.URL, GroupVersion: testapi.Default.GroupVersion()}) + recyclerClient := client.NewOrDie(&client.Config{Host: s.URL, GroupVersion: testapi.Default.GroupVersion()}) + testClient := client.NewOrDie(&client.Config{Host: s.URL, GroupVersion: testapi.Default.GroupVersion()}) binder := persistentvolumecontroller.NewPersistentVolumeClaimBinder(binderClient, 1*time.Second) binder.Run() diff --git a/test/integration/scheduler_test.go b/test/integration/scheduler_test.go index 548c88b07a1..83a3844bec3 100644 --- a/test/integration/scheduler_test.go +++ b/test/integration/scheduler_test.go @@ -93,7 +93,7 @@ func TestUnschedulableNodes(t *testing.T) { StorageVersions: storageVersions, }) - restClient := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) + restClient := client.NewOrDie(&client.Config{Host: s.URL, GroupVersion: testapi.Default.GroupVersion()}) schedulerConfigFactory := factory.NewConfigFactory(restClient, nil) schedulerConfig, err := schedulerConfigFactory.Create() @@ -344,10 +344,10 @@ func BenchmarkScheduling(b *testing.B) { }) c := client.NewOrDie(&client.Config{ - Host: s.URL, - Version: testapi.Default.Version(), - QPS: 5000.0, - Burst: 5000, + Host: s.URL, + GroupVersion: testapi.Default.GroupVersion(), + QPS: 5000.0, + Burst: 5000, }) schedulerConfigFactory := factory.NewConfigFactory(c, nil) diff --git a/test/integration/secret_test.go b/test/integration/secret_test.go index 4df513252d7..79b4dea98db 100644 --- a/test/integration/secret_test.go +++ b/test/integration/secret_test.go @@ -84,7 +84,7 @@ func TestSecrets(t *testing.T) { }) framework.DeleteAllEtcdKeys() - client := client.NewOrDie(&client.Config{Host: s.URL, Version: testapi.Default.Version()}) + client := client.NewOrDie(&client.Config{Host: s.URL, GroupVersion: testapi.Default.GroupVersion()}) DoTestSecrets(t, client, testapi.Default.Version()) } diff --git a/test/integration/service_account_test.go b/test/integration/service_account_test.go index 2e0c05c13f2..4ebca474948 100644 --- a/test/integration/service_account_test.go +++ b/test/integration/service_account_test.go @@ -365,9 +365,9 @@ func startServiceAccountTestServer(t *testing.T) (*client.Client, client.Config, })) // Anonymous client config - clientConfig := client.Config{Host: apiServer.URL, Version: testapi.Default.Version()} + clientConfig := client.Config{Host: apiServer.URL, GroupVersion: testapi.Default.GroupVersion()} // Root client - rootClient := client.NewOrDie(&client.Config{Host: apiServer.URL, Version: testapi.Default.Version(), BearerToken: rootToken}) + rootClient := client.NewOrDie(&client.Config{Host: apiServer.URL, GroupVersion: testapi.Default.GroupVersion(), BearerToken: rootToken}) // Set up two authenticators: // 1. A token authenticator that maps the rootToken to the "root" user