From dca7363459d2e3a594dcdeaf2ae593f7cdead3c9 Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Tue, 28 Oct 2014 17:20:40 -0700 Subject: [PATCH] Serve API version list, test with an integration test. --- cmd/integration/integration.go | 12 ++++++++++++ pkg/apiserver/apiserver.go | 7 +++++++ pkg/client/client.go | 15 +++++++++++++++ pkg/client/fake.go | 5 +++++ pkg/master/master.go | 2 ++ pkg/version/version.go | 6 ++++++ 6 files changed, 47 insertions(+) diff --git a/cmd/integration/integration.go b/cmd/integration/integration.go index 373d1ccca405c..a29eb8c6a7192 100644 --- a/cmd/integration/integration.go +++ b/cmd/integration/integration.go @@ -251,6 +251,17 @@ func runReplicationControllerTest(c *client.Client) { glog.Infof("Pods created") } +func runAPIVersionsTest(c *client.Client) { + v, err := c.ServerAPIVersions() + if err != nil { + glog.Fatalf("failed to get api versions: %v", err) + } + if e, a := []string{"v1beta1", "v1beta2"}, v.Versions; !reflect.DeepEqual(e, a) { + glog.Fatalf("Expected version list '%v', got '%v'", e, a) + } + glog.Infof("Version test passed") +} + func runAtomicPutTest(c *client.Client) { var svc api.Service err := c.Post().Path("services").Body( @@ -426,6 +437,7 @@ func main() { runReplicationControllerTest, runAtomicPutTest, runServiceTest, + runAPIVersionsTest, } var wg sync.WaitGroup wg.Add(len(testFuncs)) diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index d1e565dcd8db9..1af55671bd6e6 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -135,6 +135,13 @@ func handleVersion(w http.ResponseWriter, req *http.Request) { writeRawJSON(http.StatusOK, version.Get(), w) } +// APIVersionHandler returns a handler which will list the provided versions as available. +func APIVersionHandler(versions ...string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + writeRawJSON(http.StatusOK, version.APIVersions{Versions: versions}, w) + }) +} + // writeJSON renders an object as JSON to the response. func writeJSON(statusCode int, codec runtime.Codec, object runtime.Object, w http.ResponseWriter) { output, err := codec.Encode(object) diff --git a/pkg/client/client.go b/pkg/client/client.go index 367aaff3030a0..1773ab85775a9 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -62,6 +62,7 @@ func (c *Client) Services(namespace string) ServiceInterface { // VersionInterface has a method to retrieve the server version. type VersionInterface interface { ServerVersion() (*version.Info, error) + ServerAPIVersions() (*version.APIVersions, error) } // APIStatus is exposed by errors that can be converted to an api.Status object @@ -88,3 +89,17 @@ func (c *Client) ServerVersion() (*version.Info, error) { } return &info, nil } + +// ServerAPIVersions retrieves and parses the list of API versions the server supports. +func (c *Client) ServerAPIVersions() (*version.APIVersions, error) { + body, err := c.Get().AbsPath("/api").Do().Raw() + if err != nil { + return nil, err + } + var v version.APIVersions + err = json.Unmarshal(body, &v) + if err != nil { + return nil, fmt.Errorf("Got '%s': %v", string(body), err) + } + return &v, nil +} diff --git a/pkg/client/fake.go b/pkg/client/fake.go index 6c7135b3fe8f7..b7a508ad9eaea 100644 --- a/pkg/client/fake.go +++ b/pkg/client/fake.go @@ -70,3 +70,8 @@ func (c *Fake) ServerVersion() (*version.Info, error) { versionInfo := version.Get() return &versionInfo, nil } + +func (c *Fake) ServerAPIVersions() (*version.APIVersions, error) { + c.Actions = append(c.Actions, FakeAction{Action: "get-apiversions", Value: nil}) + return &version.APIVersions{Versions: []string{"v1beta1", "v1beta2"}}, nil +} diff --git a/pkg/master/master.go b/pkg/master/master.go index 627e5475bab7f..33ddc974e5831 100644 --- a/pkg/master/master.go +++ b/pkg/master/master.go @@ -190,6 +190,8 @@ func (m *Master) init(c *Config) { } apiserver.NewAPIGroup(m.API_v1beta1()).InstallREST(m.mux, c.APIPrefix+"/v1beta1") apiserver.NewAPIGroup(m.API_v1beta2()).InstallREST(m.mux, c.APIPrefix+"/v1beta2") + versionHandler := apiserver.APIVersionHandler("v1beta1", "v1beta2") + m.mux.Handle(c.APIPrefix, versionHandler) apiserver.InstallSupport(m.mux) if c.EnableLogsSupport { apiserver.InstallLogsSupport(m.mux) diff --git a/pkg/version/version.go b/pkg/version/version.go index 1343e4bde265d..5110d1a10ba51 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -45,3 +45,9 @@ func Get() Info { func (info Info) String() string { return info.GitVersion } + +// APIVersions lists the api versions that are available, to allow +// version negotiation. +type APIVersions struct { + Versions []string `json:"versions" yaml:"versions"` +}