diff --git a/pkg/client/client.go b/pkg/client/client.go index b60e7880cf5..8a92fc6ce3f 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -44,7 +44,7 @@ func (c *Client) ReplicationControllers(namespace string) ReplicationControllerI } func (c *Client) Nodes() NodeInterface { - return newNodes(c, c.preV1Beta3) + return newNodes(c) } func (c *Client) Events(namespace string) EventInterface { @@ -78,9 +78,6 @@ type APIStatus interface { // Client is the implementation of a Kubernetes client. type Client struct { *RESTClient - - // preV1Beta3 is true for v1beta1 and v1beta2 - preV1Beta3 bool } // ServerVersion retrieves and parses the server's version. @@ -132,3 +129,8 @@ func IsTimeout(err error) bool { } return false } + +// preV1Beta3 returns true if the provided API version is an API introduced before v1beta3. +func preV1Beta3(version string) bool { + return version == "v1beta1" || version == "v1beta2" +} diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index b6180fc17ae..34ba0290e59 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -165,7 +165,7 @@ func (c *testClient) ValidateCommon(t *testing.T, err error) { // buildResourcePath is a convenience function for knowing if a namespace should be in a path param or not func buildResourcePath(namespace, resource string) string { if len(namespace) > 0 { - if NamespaceInPathFor(testapi.Version()) { + if !(testapi.Version() == "v1beta1" || testapi.Version() == "v1beta2") { return path.Join("ns", namespace, resource) } } @@ -183,7 +183,7 @@ func buildQueryValues(namespace string, query url.Values) url.Values { } } if len(namespace) > 0 { - if !NamespaceInPathFor(testapi.Version()) { + if testapi.Version() == "v1beta1" || testapi.Version() == "v1beta2" { v.Set("namespace", namespace) } } @@ -765,7 +765,7 @@ func TestNewMinionPath(t *testing.T) { Response: Response{StatusCode: 200}, } cl := c.Setup() - cl.preV1Beta3 = false + cl.apiVersion = "v1beta3" err := cl.Nodes().Delete("foo") c.Validate(t, nil, err) } diff --git a/pkg/client/fake.go b/pkg/client/fake.go index 0ed9b4e0838..7cb4c5d059b 100644 --- a/pkg/client/fake.go +++ b/pkg/client/fake.go @@ -90,23 +90,28 @@ func (f HTTPClientFunc) Do(req *http.Request) (*http.Response, error) { type FakeRESTClient struct { Client HTTPClient Codec runtime.Codec + Legacy bool Req *http.Request Resp *http.Response Err error } func (c *FakeRESTClient) Get() *Request { - return NewRequest(c, "GET", &url.URL{Host: "localhost"}, c.Codec, true) + return NewRequest(c, "GET", &url.URL{Host: "localhost"}, c.Codec, c.Legacy, c.Legacy) } + func (c *FakeRESTClient) Put() *Request { - return NewRequest(c, "PUT", &url.URL{Host: "localhost"}, c.Codec, true) + return NewRequest(c, "PUT", &url.URL{Host: "localhost"}, c.Codec, c.Legacy, c.Legacy) } + func (c *FakeRESTClient) Post() *Request { - return NewRequest(c, "POST", &url.URL{Host: "localhost"}, c.Codec, true) + return NewRequest(c, "POST", &url.URL{Host: "localhost"}, c.Codec, c.Legacy, c.Legacy) } + func (c *FakeRESTClient) Delete() *Request { - return NewRequest(c, "DELETE", &url.URL{Host: "localhost"}, c.Codec, true) + return NewRequest(c, "DELETE", &url.URL{Host: "localhost"}, c.Codec, c.Legacy, c.Legacy) } + func (c *FakeRESTClient) Do(req *http.Request) (*http.Response, error) { c.Req = req if c.Client != HTTPClient(nil) { diff --git a/pkg/client/helper.go b/pkg/client/helper.go index ac8c66780a2..180c5b08414 100644 --- a/pkg/client/helper.go +++ b/pkg/client/helper.go @@ -24,6 +24,7 @@ import ( "strings" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" + "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" ) // Config holds the common attributes that can be passed to a Kubernetes client on @@ -34,9 +35,19 @@ 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. If not specified, the client will use - // the preferred version. + // Version 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 + // LegacyBehavior defines whether the RESTClient should follow conventions that + // existed prior to v1beta3 in Kubernetes - namely, namespace (if specified) + // not being part of the path, and resource names allowing mixed case. Set to + // true when using Kubernetes v1beta1 or v1beta2. + LegacyBehavior bool + // 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. + Codec runtime.Codec // Server requires Basic authentication Username string @@ -80,16 +91,14 @@ type KubeletConfig struct { // is not valid. func New(c *Config) (*Client, error) { config := *c - if config.Prefix == "" { - config.Prefix = "/api" + if err := SetKubernetesDefaults(&config); err != nil { + return nil, err } client, err := RESTClientFor(&config) if err != nil { return nil, err } - version := defaultVersionFor(&config) - isPreV1Beta3 := (version == "v1beta1" || version == "v1beta2") - return &Client{client, isPreV1Beta3}, nil + return &Client{client}, nil } // NewOrDie creates a Kubernetes client and panics if the provided API version is not recognized. @@ -101,15 +110,37 @@ func NewOrDie(c *Config) *Client { return client } -// RESTClientFor returns a RESTClient that satisfies the requested attributes on a client Config -// object. -func RESTClientFor(config *Config) (*RESTClient, error) { - version := defaultVersionFor(config) - - // Set version +// SetKubernetesDefaults sets default values on the provided client config for accessing the +// Kubernetes API or returns an error if any of the defaults are impossible or invalid. +func SetKubernetesDefaults(config *Config) error { + if config.Prefix == "" { + config.Prefix = "/api" + } + if len(config.Version) == 0 { + config.Version = defaultVersionFor(config) + } + version := config.Version versionInterfaces, err := latest.InterfacesFor(version) if err != nil { - return nil, fmt.Errorf("API version '%s' is not recognized (valid values: %s)", version, strings.Join(latest.Versions, ", ")) + return fmt.Errorf("API version '%s' is not recognized (valid values: %s)", version, strings.Join(latest.Versions, ", ")) + } + if config.Codec == nil { + config.Codec = versionInterfaces.Codec + } + config.LegacyBehavior = (version == "v1beta1" || version == "v1beta2") + return nil +} + +// RESTClientFor returns a RESTClient that satisfies the requested attributes on a client Config +// object. Note that a RESTClient may require fields that are optional when initializing a Client. +// 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.Codec == nil { + return nil, fmt.Errorf("Codec is required when initializing a RESTClient") } baseURL, err := defaultServerUrlFor(config) @@ -117,7 +148,7 @@ func RESTClientFor(config *Config) (*RESTClient, error) { return nil, err } - client := NewRESTClient(baseURL, versionInterfaces.Codec, NamespaceInPathFor(version)) + client := NewRESTClient(baseURL, config.Version, config.Codec, config.LegacyBehavior) transport, err := TransportFor(config) if err != nil { @@ -229,9 +260,9 @@ func IsConfigTransportTLS(config *Config) bool { return baseURL.Scheme == "https" } -// defaultServerUrlFor is shared between IsConfigTransportTLS and RESTClientFor +// defaultServerUrlFor is shared between IsConfigTransportTLS and RESTClientFor. It +// requires Host and Version to be set prior to being called. func defaultServerUrlFor(config *Config) (*url.URL, error) { - version := defaultVersionFor(config) // TODO: move the default to secure when the apiserver supports TLS by default // config.Insecure is taken to mean "I want HTTPS but don't bother checking the certs against a CA." defaultTLS := config.CertFile != "" || config.Insecure @@ -239,7 +270,7 @@ func defaultServerUrlFor(config *Config) (*url.URL, error) { if host == "" { host = "localhost" } - return DefaultServerURL(host, config.Prefix, version, defaultTLS) + return DefaultServerURL(host, config.Prefix, config.Version, defaultTLS) } // defaultVersionFor is shared between defaultServerUrlFor and RESTClientFor @@ -252,9 +283,3 @@ func defaultVersionFor(config *Config) string { } return version } - -// namespaceInPathFor is used to control what api version should use namespace in url paths -func NamespaceInPathFor(version string) bool { - // we use query param for v1beta1/v1beta2, v1beta3+ will use path param - return (version != "v1beta1" && version != "v1beta2") -} diff --git a/pkg/client/helper_test.go b/pkg/client/helper_test.go index 485e7eb425a..0053d0cc13e 100644 --- a/pkg/client/helper_test.go +++ b/pkg/client/helper_test.go @@ -85,6 +85,10 @@ func TestIsConfigTransportTLS(t *testing.T) { }, } for _, testCase := range testCases { + if err := SetKubernetesDefaults(testCase.Config); err != nil { + t.Errorf("setting defaults failed for %#v: %v", testCase.Config, err) + continue + } useTLS := IsConfigTransportTLS(testCase.Config) if testCase.TransportTLS != useTLS { t.Errorf("expected %v for %#v", testCase.TransportTLS, testCase.Config) diff --git a/pkg/client/minions.go b/pkg/client/minions.go index e4f88edac59..2ed08688723 100644 --- a/pkg/client/minions.go +++ b/pkg/client/minions.go @@ -35,18 +35,17 @@ type NodeInterface interface { // nodes implements NodesInterface type nodes struct { - r *Client - preV1Beta3 bool + r *Client } // newNodes returns a nodes object. Uses "minions" as the // URL resource name for v1beta1 and v1beta2. -func newNodes(c *Client, isPreV1Beta3 bool) *nodes { - return &nodes{c, isPreV1Beta3} +func newNodes(c *Client) *nodes { + return &nodes{c} } func (c *nodes) resourceName() string { - if c.preV1Beta3 { + if preV1Beta3(c.r.APIVersion()) { return "minions" } return "nodes" diff --git a/pkg/client/request.go b/pkg/client/request.go index f7bdf68fcf3..cb440ed02dc 100644 --- a/pkg/client/request.go +++ b/pkg/client/request.go @@ -89,8 +89,12 @@ type Request struct { // whether to poll. poller PollFunc - // If true, put ns/ in path; if false, add "?namespace=" as a query parameter - namespaceInPath bool + // If true, add "?namespace=" as a query parameter, if false put ns/ in path + // Query parameter is considered legacy behavior + namespaceInQuery bool + // If true, lowercase resource prior to inserting into a path, if false, leave it as is. Preserving + // case is considered legacy behavior. + preserveResourceCase bool // generic components accessible via method setters path string @@ -110,15 +114,18 @@ type Request struct { body io.Reader } -// NewRequest creates a new request with the core attributes. -func NewRequest(client HTTPClient, verb string, baseURL *url.URL, codec runtime.Codec, namespaceInPath bool) *Request { +// NewRequest creates a new request helper object for accessing runtime.Objects on a server. +func NewRequest(client HTTPClient, verb string, baseURL *url.URL, + codec runtime.Codec, namespaceInQuery bool, preserveResourceCase bool) *Request { return &Request{ - client: client, - verb: verb, - baseURL: baseURL, - codec: codec, - namespaceInPath: namespaceInPath, - path: baseURL.Path, + client: client, + verb: verb, + baseURL: baseURL, + path: baseURL.Path, + + codec: codec, + namespaceInQuery: namespaceInQuery, + preserveResourceCase: preserveResourceCase, } } @@ -323,11 +330,15 @@ func (r *Request) Poller(poller PollFunc) *Request { func (r *Request) finalURL() string { p := r.path - if r.namespaceInPath { + if !r.namespaceInQuery { p = path.Join(p, "ns", r.namespace) } if len(r.resource) != 0 { - p = path.Join(p, r.resource) + resource := r.resource + if !r.preserveResourceCase { + resource = strings.ToLower(resource) + } + p = path.Join(p, resource) } // Join trims trailing slashes, so preserve r.path's trailing slash for backwards compat if nothing was changed if len(r.resourceName) != 0 || len(r.subpath) != 0 { @@ -342,7 +353,7 @@ func (r *Request) finalURL() string { query.Add(key, value) } - if !r.namespaceInPath && len(r.namespace) > 0 { + if r.namespaceInQuery && len(r.namespace) > 0 { query.Add("namespace", r.namespace) } diff --git a/pkg/client/request_test.go b/pkg/client/request_test.go index 3740692669c..2891615187a 100644 --- a/pkg/client/request_test.go +++ b/pkg/client/request_test.go @@ -75,21 +75,21 @@ func TestRequestWithErrorWontChange(t *testing.T) { } func TestRequestPreservesBaseTrailingSlash(t *testing.T) { - r := &Request{baseURL: &url.URL{}, path: "/path/"} + r := &Request{baseURL: &url.URL{}, path: "/path/", namespaceInQuery: true} if s := r.finalURL(); s != "/path/" { t.Errorf("trailing slash should be preserved: %s", s) } } func TestRequestAbsPathPreservesTrailingSlash(t *testing.T) { - r := (&Request{baseURL: &url.URL{}}).AbsPath("/foo/") + r := (&Request{baseURL: &url.URL{}, namespaceInQuery: true}).AbsPath("/foo/") if s := r.finalURL(); s != "/foo/" { t.Errorf("trailing slash should be preserved: %s", s) } } func TestRequestAbsPathJoins(t *testing.T) { - r := (&Request{baseURL: &url.URL{}}).AbsPath("foo/bar", "baz") + r := (&Request{baseURL: &url.URL{}, namespaceInQuery: true}).AbsPath("foo/bar", "baz") if s := r.finalURL(); s != "foo/bar/baz" { t.Errorf("trailing slash should be preserved: %s", s) } @@ -100,6 +100,7 @@ func TestRequestSetsNamespace(t *testing.T) { baseURL: &url.URL{ Path: "/", }, + namespaceInQuery: true, }).Namespace("foo") if r.namespace == "" { t.Errorf("namespace should be set: %#v", r) @@ -112,7 +113,6 @@ func TestRequestSetsNamespace(t *testing.T) { baseURL: &url.URL{ Path: "/", }, - namespaceInPath: true, }).Namespace("foo") if s := r.finalURL(); s != "ns/foo" { t.Errorf("namespace should be in path: %s", s) @@ -121,9 +121,8 @@ func TestRequestSetsNamespace(t *testing.T) { func TestRequestOrdersNamespaceInPath(t *testing.T) { r := (&Request{ - baseURL: &url.URL{}, - path: "/test/", - namespaceInPath: true, + baseURL: &url.URL{}, + path: "/test/", }).Name("bar").Resource("baz").Namespace("foo") if s := r.finalURL(); s != "/test/ns/foo/baz/bar" { t.Errorf("namespace should be in order in path: %s", s) @@ -212,7 +211,7 @@ func TestTransformResponse(t *testing.T) { {Response: &http.Response{StatusCode: 200, Body: ioutil.NopCloser(bytes.NewReader(invalid))}, Data: invalid}, } for i, test := range testCases { - r := NewRequest(nil, "", uri, testapi.Codec(), true) + r := NewRequest(nil, "", uri, testapi.Codec(), true, true) if test.Response.Body == nil { test.Response.Body = ioutil.NopCloser(bytes.NewReader([]byte{})) } diff --git a/pkg/client/restclient.go b/pkg/client/restclient.go index 581a75bbfc1..1cda59391ab 100644 --- a/pkg/client/restclient.go +++ b/pkg/client/restclient.go @@ -35,10 +35,13 @@ import ( // Most consumers should use client.New() to get a Kubernetes API client. type RESTClient struct { baseURL *url.URL + // A string identifying the version of the API this client is expected to use. + apiVersion string - // namespaceInPath controls if URLs should encode the namespace as path param instead of query param - // needed for backward compatibility - namespaceInPath bool + // LegacyBehavior controls if URLs should encode the namespace as a query param, + // and if resource case is preserved for supporting older API conventions of + // Kubernetes. Newer clients should leave this false. + LegacyBehavior bool // Codec is the encoding and decoding scheme that applies to a particular set of // REST resources. @@ -59,10 +62,9 @@ type RESTClient struct { // NewRESTClient creates a new RESTClient. This client performs generic REST functions // such as Get, Put, Post, and Delete on specified paths. Codec controls encoding and -// decoding of responses from the server. If the namespace should be specified as part -// of the path (after the resource), set namespaceInPath to true, otherwise it will be -// passed as "namespace" in the query string. -func NewRESTClient(baseURL *url.URL, c runtime.Codec, namespaceInPath bool) *RESTClient { +// decoding of responses from the server. If this client should use the older, legacy +// API conventions from Kubernetes API v1beta1 and v1beta2, set legacyBehavior true. +func NewRESTClient(baseURL *url.URL, apiVersion string, c runtime.Codec, legacyBehavior bool) *RESTClient { base := *baseURL if !strings.HasSuffix(base.Path, "/") { base.Path += "/" @@ -71,10 +73,12 @@ func NewRESTClient(baseURL *url.URL, c runtime.Codec, namespaceInPath bool) *RES base.Fragment = "" return &RESTClient{ - baseURL: &base, - Codec: c, + baseURL: &base, + apiVersion: apiVersion, - namespaceInPath: namespaceInPath, + Codec: c, + + LegacyBehavior: legacyBehavior, // Make asynchronous requests by default Sync: false, @@ -106,7 +110,7 @@ func (c *RESTClient) Verb(verb string) *Request { if poller == nil { poller = c.DefaultPoll } - return NewRequest(c.Client, verb, c.baseURL, c.Codec, c.namespaceInPath).Poller(poller).Sync(c.Sync).Timeout(c.Timeout) + return NewRequest(c.Client, verb, c.baseURL, c.Codec, c.LegacyBehavior, c.LegacyBehavior).Poller(poller).Sync(c.Sync).Timeout(c.Timeout) } // Post begins a POST request. Short for c.Verb("POST"). @@ -134,6 +138,7 @@ func (c *RESTClient) Operation(name string) *Request { return c.Get().Resource("operations").Name(name).Sync(false).NoPoll() } +// DefaultPoll performs a polling action based on the PollPeriod set on the Client. func (c *RESTClient) DefaultPoll(name string) (*Request, bool) { if c.PollPeriod == 0 { return nil, false @@ -143,3 +148,8 @@ func (c *RESTClient) DefaultPoll(name string) (*Request, bool) { // Make a poll request return c.Operation(name).Poller(c.DefaultPoll), true } + +// APIVersion returns the APIVersion this RESTClient is expected to use. +func (c *RESTClient) APIVersion() string { + return c.apiVersion +} diff --git a/pkg/client/restclient_test.go b/pkg/client/restclient_test.go index b859aced001..31756d72adb 100644 --- a/pkg/client/restclient_test.go +++ b/pkg/client/restclient_test.go @@ -31,19 +31,19 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) -func TestChecksCodec(t *testing.T) { +func TestSetsCodec(t *testing.T) { testCases := map[string]struct { Err bool Prefix string Codec runtime.Codec }{ - "v1beta1": {false, "/v1beta1/", v1beta1.Codec}, - "": {false, "/v1beta1/", v1beta1.Codec}, - "v1beta2": {false, "/v1beta2/", v1beta2.Codec}, + "v1beta1": {false, "/api/v1beta1/", v1beta1.Codec}, + "": {false, "/api/v1beta1/", v1beta1.Codec}, + "v1beta2": {false, "/api/v1beta2/", v1beta2.Codec}, "v1beta3": {true, "", nil}, } for version, expected := range testCases { - client, err := RESTClientFor(&Config{Host: "127.0.0.1", Version: version}) + client, err := New(&Config{Host: "127.0.0.1", Version: version}) switch { case err == nil && expected.Err: t.Errorf("expected error but was nil") @@ -54,15 +54,70 @@ func TestChecksCodec(t *testing.T) { case err != nil: continue } - if e, a := expected.Prefix, client.baseURL.Path; e != a { + if e, a := expected.Prefix, client.RESTClient.baseURL.Path; e != a { t.Errorf("expected %#v, got %#v", e, a) } - if e, a := expected.Codec, client.Codec; e != a { + if e, a := expected.Codec, client.RESTClient.Codec; e != a { t.Errorf("expected %#v, got %#v", e, a) } } } +func TestSetDefaults(t *testing.T) { + testCases := []struct { + Config Config + After Config + Err bool + }{ + { + Config{}, + Config{ + Prefix: "/api", + Version: latest.Version, + Codec: latest.Codec, + LegacyBehavior: (latest.Version == "v1beta1" || latest.Version == "v1beta2"), + }, + false, + }, + { + Config{ + Version: "not_an_api", + }, + Config{}, + true, + }, + } + for _, testCase := range testCases { + val := &testCase.Config + err := SetKubernetesDefaults(val) + switch { + case err == nil && testCase.Err: + t.Errorf("expected error but was nil") + continue + case err != nil && !testCase.Err: + t.Errorf("unexpected error %v", err) + continue + case err != nil: + continue + } + if *val != testCase.After { + t.Errorf("unexpected result object: %#v", val) + } + } +} + +func TestRESTClientRequires(t *testing.T) { + if _, err := RESTClientFor(&Config{Host: "127.0.0.1", Version: "", Codec: testapi.Codec()}); err == nil { + t.Errorf("unexpected non-error") + } + if _, err := RESTClientFor(&Config{Host: "127.0.0.1", Version: "v1beta1"}); err == nil { + t.Errorf("unexpected non-error") + } + if _, err := RESTClientFor(&Config{Host: "127.0.0.1", Version: testapi.Version(), Codec: testapi.Codec()}); err != nil { + t.Errorf("unexpected error: %v", err) + } +} + func TestValidatesHostParameter(t *testing.T) { testCases := []struct { Host string @@ -81,7 +136,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: "v1beta1"}) + c, err := RESTClientFor(&Config{Host: testCase.Host, Prefix: testCase.Prefix, Version: "v1beta1", Codec: testapi.Codec()}) switch { case err == nil && testCase.Err: t.Errorf("expected error but was nil") @@ -110,7 +165,14 @@ func TestDoRequestBearer(t *testing.T) { testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() request, _ := http.NewRequest("GET", testServer.URL, nil) - c, err := RESTClientFor(&Config{Host: testServer.URL, BearerToken: "test"}) + c, err := RESTClientFor(&Config{ + Host: testServer.URL, + Version: testapi.Version(), + Codec: testapi.Codec(), + LegacyBehavior: true, + + BearerToken: "test", + }) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -133,7 +195,14 @@ func TestDoRequestAccepted(t *testing.T) { } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() - c, err := RESTClientFor(&Config{Host: testServer.URL, Username: "test", Version: testapi.Version()}) + c, err := RESTClientFor(&Config{ + Host: testServer.URL, + Version: testapi.Version(), + Codec: testapi.Codec(), + LegacyBehavior: true, + + Username: "test", + }) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -167,7 +236,15 @@ func TestDoRequestAcceptedSuccess(t *testing.T) { } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() - c, err := RESTClientFor(&Config{Host: testServer.URL, Username: "user", Password: "pass", Version: testapi.Version()}) + c, err := RESTClientFor(&Config{ + Host: testServer.URL, + Version: testapi.Version(), + Codec: testapi.Codec(), + LegacyBehavior: true, + + Username: "user", + Password: "pass", + }) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -198,7 +275,12 @@ func TestDoRequestFailed(t *testing.T) { } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() - c, err := RESTClientFor(&Config{Host: testServer.URL}) + c, err := RESTClientFor(&Config{ + Host: testServer.URL, + Version: testapi.Version(), + Codec: testapi.Codec(), + LegacyBehavior: true, + }) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -226,7 +308,15 @@ func TestDoRequestCreated(t *testing.T) { } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() - c, err := RESTClientFor(&Config{Host: testServer.URL, Username: "user", Password: "pass", Version: testapi.Version()}) + c, err := RESTClientFor(&Config{ + Host: testServer.URL, + Version: testapi.Version(), + Codec: testapi.Codec(), + LegacyBehavior: true, + + Username: "user", + Password: "pass", + }) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index e5bac102ceb..40614acb295 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -48,7 +48,7 @@ func getFakeClient(t *testing.T, validURLs []string) (ClientPosterFunc, *httptes return func(mapping *meta.RESTMapping) (RESTClientPoster, error) { fakeCodec := runtime.CodecFor(api.Scheme, "v1beta1") fakeUri, _ := url.Parse(server.URL + "/api/v1beta1") - return client.NewRESTClient(fakeUri, fakeCodec, false), nil + return client.NewRESTClient(fakeUri, "v1beta1", fakeCodec, true), nil }, server } diff --git a/pkg/controller/replication_controller_test.go b/pkg/controller/replication_controller_test.go index 21f17d768d5..877882ece57 100644 --- a/pkg/controller/replication_controller_test.go +++ b/pkg/controller/replication_controller_test.go @@ -38,7 +38,7 @@ import ( ) func makeNamespaceURL(namespace, suffix string) string { - if client.NamespaceInPathFor(testapi.Version()) { + if !(testapi.Version() == "v1beta1" || testapi.Version() == "v1beta2") { return makeURL("/ns/" + namespace + suffix) } return makeURL(suffix + "?namespace=" + namespace) diff --git a/plugin/pkg/scheduler/factory/factory_test.go b/plugin/pkg/scheduler/factory/factory_test.go index bfc635503da..1b05d93c76c 100644 --- a/plugin/pkg/scheduler/factory/factory_test.go +++ b/plugin/pkg/scheduler/factory/factory_test.go @@ -88,7 +88,7 @@ func TestPollMinions(t *testing.T) { } func makeNamespaceURL(namespace, suffix string, isClient bool) string { - if client.NamespaceInPathFor(testapi.Version()) { + if !(testapi.Version() == "v1beta1" || testapi.Version() == "v1beta2") { return makeURL("/ns/" + namespace + suffix) } // if this is a url the client should call, encode the url