Merge pull request #9280 from caesarxuchao/make-v1-preferred

Make v1 the preferred api version
This commit is contained in:
Quinton Hoole 2015-06-05 15:23:14 -07:00
commit 6ff203e9da
6 changed files with 42 additions and 36 deletions

View File

@ -124,7 +124,7 @@ for version in "${kube_api_versions[@]}"; do
-s "http://127.0.0.1:${API_PORT}" -s "http://127.0.0.1:${API_PORT}"
--match-server-version --match-server-version
) )
[ "$(kubectl get nodes -t '{{ .apiVersion }}' "${kube_flags[@]}")" == "v1beta3" ] [ "$(kubectl get nodes -t '{{ .apiVersion }}' "${kube_flags[@]}")" == "v1" ]
else else
kube_flags=( kube_flags=(
-s "http://127.0.0.1:${API_PORT}" -s "http://127.0.0.1:${API_PORT}"

View File

@ -70,11 +70,11 @@ func TestInterfacesFor(t *testing.T) {
} }
func TestRESTMapper(t *testing.T) { func TestRESTMapper(t *testing.T) {
if v, k, err := RESTMapper.VersionAndKindForResource("replicationcontrollers"); err != nil || v != "v1beta3" || k != "ReplicationController" { if v, k, err := RESTMapper.VersionAndKindForResource("replicationcontrollers"); err != nil || v != "v1" || k != "ReplicationController" {
t.Errorf("unexpected version mapping: %s %s %v", v, k, err) t.Errorf("unexpected version mapping: %s %s %v", v, k, err)
} }
if m, err := RESTMapper.RESTMapping("PodTemplate", ""); err != nil || m.APIVersion != "v1beta3" || m.Resource != "podtemplates" { if m, err := RESTMapper.RESTMapping("PodTemplate", ""); err != nil || m.APIVersion != "v1" || m.Resource != "podtemplates" {
t.Errorf("unexpected version mapping: %#v %v", m, err) t.Errorf("unexpected version mapping: %#v %v", m, err)
} }

View File

@ -35,7 +35,7 @@ func init() {
} }
// The default list of supported api versions, in order of most preferred to the least. // The default list of supported api versions, in order of most preferred to the least.
defaultSupportedVersions := "v1beta3,v1" defaultSupportedVersions := "v1,v1beta3"
// Env var KUBE_API_VERSIONS is a comma separated list of API versions that should be registered in the scheme. // Env var KUBE_API_VERSIONS is a comma separated list of API versions that should be registered in the scheme.
// The versions should be in the order of most preferred to the least. // The versions should be in the order of most preferred to the least.
supportedVersions := os.Getenv("KUBE_API_VERSIONS") supportedVersions := os.Getenv("KUBE_API_VERSIONS")

View File

@ -66,7 +66,8 @@ func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) {
scheme := runtime.NewScheme() scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName("", "Type", &internalType{}) scheme.AddKnownTypeWithName("", "Type", &internalType{})
scheme.AddKnownTypeWithName("unlikelyversion", "Type", &externalType{}) scheme.AddKnownTypeWithName("unlikelyversion", "Type", &externalType{})
scheme.AddKnownTypeWithName("v1beta1", "Type", &ExternalType2{}) //This tests that kubectl will not confuse the external scheme with the internal scheme, even when they accidentally have versions of the same name.
scheme.AddKnownTypeWithName(testapi.Version(), "Type", &ExternalType2{})
codec := runtime.CodecFor(scheme, "unlikelyversion") codec := runtime.CodecFor(scheme, "unlikelyversion")
validVersion := testapi.Version() validVersion := testapi.Version()

View File

@ -147,34 +147,40 @@ func TestGetUnknownSchemaObject(t *testing.T) {
// api.Scheme, which may not have access to all objects, and not all objects are at the same // api.Scheme, which may not have access to all objects, and not all objects are at the same
// internal versioning scheme. This test verifies that two isolated schemes (Test, and api.Scheme) // internal versioning scheme. This test verifies that two isolated schemes (Test, and api.Scheme)
// can be conjoined into a single output object. // can be conjoined into a single output object.
//
// The expected behavior of the `kubectl get` command is:
// 1. objects using unrecognized schemes will always be returned using that scheme/version, "unlikelyversion" in this test;
// 2. if the specified output-version is a recognized, valid Scheme, then the list should use that scheme, and otherwise it will default to the client version, latest.Version in this test;
// 3a. if the specified output-version is a recognized, valid Scheme, in which the requested object (replicationcontroller) can be represented, then the object should be returned using that version;
// 3b. otherwise if the specified output-version is unrecognized, but the requested object (replicationcontroller) is recognized by the client's codec, then it will be converted to the client version, latest.Version in this test.
func TestGetUnknownSchemaObjectListGeneric(t *testing.T) { func TestGetUnknownSchemaObjectListGeneric(t *testing.T) {
testCases := map[string]struct { testCases := map[string]struct {
output string outputVersion string
list string listVersion string
obj1 string testtypeVersion string
obj2 string rcVersion string
}{ }{
"handles specific version": { "handles specific version": {
output: "v1", outputVersion: latest.Version,
list: "v1", listVersion: latest.Version,
obj1: "unlikelyversion", testtypeVersion: "unlikelyversion",
obj2: "v1", rcVersion: latest.Version,
}, },
"handles second specific version": { "handles second specific version": {
output: "unlikelyversion", outputVersion: "unlikelyversion",
list: "v1beta3", listVersion: latest.Version,
obj1: "unlikelyversion", // doesn't have v1beta3 testtypeVersion: "unlikelyversion",
obj2: "v1beta3", // version of the API response rcVersion: latest.Version, // see expected behavior 3b
}, },
"handles common version": { "handles common version": {
output: "v1beta3", outputVersion: testapi.Version(),
list: "v1beta3", listVersion: testapi.Version(),
obj1: "unlikelyversion", // because test scheme defaults to unlikelyversion testtypeVersion: "unlikelyversion",
obj2: "v1beta3", rcVersion: testapi.Version(),
}, },
} }
for k, test := range testCases { for k, test := range testCases {
apiCodec := runtime.CodecFor(api.Scheme, "v1beta3") apiCodec := runtime.CodecFor(api.Scheme, testapi.Version())
regularClient := &client.FakeRESTClient{ regularClient := &client.FakeRESTClient{
Codec: apiCodec, Codec: apiCodec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
@ -196,7 +202,7 @@ func TestGetUnknownSchemaObjectListGeneric(t *testing.T) {
cmd := NewCmdGet(f, buf) cmd := NewCmdGet(f, buf)
cmd.SetOutput(buf) cmd.SetOutput(buf)
cmd.Flags().Set("output", "json") cmd.Flags().Set("output", "json")
cmd.Flags().Set("output-version", test.output) cmd.Flags().Set("output-version", test.outputVersion)
err := RunGet(f, buf, cmd, []string{"type/foo", "replicationcontrollers/foo"}) err := RunGet(f, buf, cmd, []string{"type/foo", "replicationcontrollers/foo"})
if err != nil { if err != nil {
t.Errorf("%s: unexpected error: %v", k, err) t.Errorf("%s: unexpected error: %v", k, err)
@ -207,14 +213,14 @@ func TestGetUnknownSchemaObjectListGeneric(t *testing.T) {
t.Errorf("%s: unexpected error: %v\n%s", k, err, buf.String()) t.Errorf("%s: unexpected error: %v\n%s", k, err, buf.String())
continue continue
} }
if out["apiVersion"] != test.list { if out["apiVersion"] != test.listVersion {
t.Errorf("%s: unexpected list: %#v", k, out) t.Errorf("%s: unexpected list: %#v", k, out)
} }
arr := out["items"].([]interface{}) arr := out["items"].([]interface{})
if arr[0].(map[string]interface{})["apiVersion"] != test.obj1 { if arr[0].(map[string]interface{})["apiVersion"] != test.testtypeVersion {
t.Errorf("%s: unexpected list: %#v", k, out) t.Errorf("%s: unexpected list: %#v", k, out)
} }
if arr[1].(map[string]interface{})["apiVersion"] != test.obj2 { if arr[1].(map[string]interface{})["apiVersion"] != test.rcVersion {
t.Errorf("%s: unexpected list: %#v", k, out) t.Errorf("%s: unexpected list: %#v", k, out)
} }
} }

View File

@ -27,7 +27,6 @@ import (
"time" "time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient" "github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient"
@ -672,7 +671,7 @@ func TestUpdateWithRetries(t *testing.T) {
Codec: codec, Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/api/v1beta3/namespaces/default/replicationcontrollers/rc" && m == "PUT": case p == testapi.ResourcePath("replicationcontrollers", "default", "rc") && m == "PUT":
update := updates[0] update := updates[0]
updates = updates[1:] updates = updates[1:]
// We should always get an update with a valid rc even when the get fails. The rc should always // We should always get an update with a valid rc even when the get fails. The rc should always
@ -685,7 +684,7 @@ func TestUpdateWithRetries(t *testing.T) {
delete(c.Spec.Selector, "baz") delete(c.Spec.Selector, "baz")
} }
return update, nil return update, nil
case p == "/api/v1beta3/namespaces/default/replicationcontrollers/rc" && m == "GET": case p == testapi.ResourcePath("replicationcontrollers", "default", "rc") && m == "GET":
get := gets[0] get := gets[0]
gets = gets[1:] gets = gets[1:]
return get, nil return get, nil
@ -695,7 +694,7 @@ func TestUpdateWithRetries(t *testing.T) {
} }
}), }),
} }
clientConfig := &client.Config{Version: latest.Version} clientConfig := &client.Config{Version: testapi.Version()}
client := client.NewOrDie(clientConfig) client := client.NewOrDie(clientConfig)
client.Client = fakeClient.Client client.Client = fakeClient.Client
@ -763,27 +762,27 @@ func TestAddDeploymentHash(t *testing.T) {
Codec: codec, Codec: codec,
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) { Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; { switch p, m := req.URL.Path, req.Method; {
case p == "/api/v1beta3/namespaces/default/pods" && m == "GET": case p == testapi.ResourcePath("pods", "default", "") && m == "GET":
if req.URL.RawQuery != "labelSelector=foo%3Dbar" { if req.URL.RawQuery != "labelSelector=foo%3Dbar" {
t.Errorf("Unexpected query string: %s", req.URL.RawQuery) t.Errorf("Unexpected query string: %s", req.URL.RawQuery)
} }
return &http.Response{StatusCode: 200, Body: objBody(codec, podList)}, nil return &http.Response{StatusCode: 200, Body: objBody(codec, podList)}, nil
case p == "/api/v1beta3/namespaces/default/pods/foo" && m == "PUT": case p == testapi.ResourcePath("pods", "default", "foo") && m == "PUT":
seen.Insert("foo") seen.Insert("foo")
obj := readOrDie(t, req, codec) obj := readOrDie(t, req, codec)
podList.Items[0] = *(obj.(*api.Pod)) podList.Items[0] = *(obj.(*api.Pod))
return &http.Response{StatusCode: 200, Body: objBody(codec, &podList.Items[0])}, nil return &http.Response{StatusCode: 200, Body: objBody(codec, &podList.Items[0])}, nil
case p == "/api/v1beta3/namespaces/default/pods/bar" && m == "PUT": case p == testapi.ResourcePath("pods", "default", "bar") && m == "PUT":
seen.Insert("bar") seen.Insert("bar")
obj := readOrDie(t, req, codec) obj := readOrDie(t, req, codec)
podList.Items[1] = *(obj.(*api.Pod)) podList.Items[1] = *(obj.(*api.Pod))
return &http.Response{StatusCode: 200, Body: objBody(codec, &podList.Items[1])}, nil return &http.Response{StatusCode: 200, Body: objBody(codec, &podList.Items[1])}, nil
case p == "/api/v1beta3/namespaces/default/pods/baz" && m == "PUT": case p == testapi.ResourcePath("pods", "default", "baz") && m == "PUT":
seen.Insert("baz") seen.Insert("baz")
obj := readOrDie(t, req, codec) obj := readOrDie(t, req, codec)
podList.Items[2] = *(obj.(*api.Pod)) podList.Items[2] = *(obj.(*api.Pod))
return &http.Response{StatusCode: 200, Body: objBody(codec, &podList.Items[2])}, nil return &http.Response{StatusCode: 200, Body: objBody(codec, &podList.Items[2])}, nil
case p == "/api/v1beta3/namespaces/default/replicationcontrollers/rc" && m == "PUT": case p == testapi.ResourcePath("replicationcontrollers", "default", "rc") && m == "PUT":
updatedRc = true updatedRc = true
return &http.Response{StatusCode: 200, Body: objBody(codec, rc)}, nil return &http.Response{StatusCode: 200, Body: objBody(codec, rc)}, nil
default: default:
@ -792,7 +791,7 @@ func TestAddDeploymentHash(t *testing.T) {
} }
}), }),
} }
clientConfig := &client.Config{Version: latest.Version} clientConfig := &client.Config{Version: testapi.Version()}
client := client.NewOrDie(clientConfig) client := client.NewOrDie(clientConfig)
client.Client = fakeClient.Client client.Client = fakeClient.Client