Refactor the client (again) to better support auth

* Allows consumers to provide their own transports for common cases.
* Supports KUBE_API_VERSION on test cases for controlling which
  api version they test against
* Provides a common flag registration method for CLIs that need
  to connect to an API server (to avoid duplicating flags)
* Ensures errors are properly returned by the server
* Add a Context field to client.Config
This commit is contained in:
Clayton Coleman
2014-09-29 20:15:00 -04:00
parent 88bf01b008
commit ff2eca97d9
26 changed files with 1281 additions and 704 deletions

View File

@@ -48,9 +48,7 @@ func TestDoRequestNewWay(t *testing.T) {
T: t,
}
testServer := httptest.NewServer(&fakeHandler)
auth := AuthInfo{User: "user", Password: "pass"}
ctx := api.NewContext()
c := NewOrDie(ctx, testServer.URL, "v1beta2", &auth)
c := NewOrDie(&Config{Host: testServer.URL, Version: "v1beta2", Username: "user", Password: "pass"})
obj, err := c.Verb("POST").
Path("foo/bar").
Path("baz").
@@ -84,9 +82,7 @@ func TestDoRequestNewWayReader(t *testing.T) {
T: t,
}
testServer := httptest.NewServer(&fakeHandler)
auth := AuthInfo{User: "user", Password: "pass"}
ctx := api.NewContext()
c := NewOrDie(ctx, testServer.URL, "v1beta1", &auth)
c := NewOrDie(&Config{Host: testServer.URL, Version: "v1beta1", Username: "user", Password: "pass"})
obj, err := c.Verb("POST").
Path("foo/bar").
Path("baz").
@@ -122,9 +118,7 @@ func TestDoRequestNewWayObj(t *testing.T) {
T: t,
}
testServer := httptest.NewServer(&fakeHandler)
auth := AuthInfo{User: "user", Password: "pass"}
ctx := api.NewContext()
c := NewOrDie(ctx, testServer.URL, "v1beta2", &auth)
c := NewOrDie(&Config{Host: testServer.URL, Version: "v1beta2", Username: "user", Password: "pass"})
obj, err := c.Verb("POST").
Path("foo/bar").
Path("baz").
@@ -173,9 +167,7 @@ func TestDoRequestNewWayFile(t *testing.T) {
T: t,
}
testServer := httptest.NewServer(&fakeHandler)
auth := AuthInfo{User: "user", Password: "pass"}
ctx := api.NewContext()
c := NewOrDie(ctx, testServer.URL, "v1beta1", &auth)
c := NewOrDie(&Config{Host: testServer.URL, Version: "v1beta1", Username: "user", Password: "pass"})
obj, err := c.Verb("POST").
Path("foo/bar").
Path("baz").
@@ -200,8 +192,7 @@ func TestDoRequestNewWayFile(t *testing.T) {
}
func TestVerbs(t *testing.T) {
ctx := api.NewContext()
c := NewOrDie(ctx, "localhost", "", nil)
c := NewOrDie(&Config{})
if r := c.Post(); r.verb != "POST" {
t.Errorf("Post verb is wrong")
}
@@ -217,9 +208,8 @@ func TestVerbs(t *testing.T) {
}
func TestAbsPath(t *testing.T) {
ctx := api.NewContext()
expectedPath := "/bar/foo"
c := NewOrDie(ctx, "localhost", "", nil)
c := NewOrDie(&Config{})
r := c.Post().Path("/foo").AbsPath(expectedPath)
if r.path != expectedPath {
t.Errorf("unexpected path: %s, expected %s", r.path, expectedPath)
@@ -227,8 +217,7 @@ func TestAbsPath(t *testing.T) {
}
func TestSync(t *testing.T) {
ctx := api.NewContext()
c := NewOrDie(ctx, "localhost", "", nil)
c := NewOrDie(&Config{})
r := c.Get()
if r.sync {
t.Errorf("sync has wrong default")
@@ -254,9 +243,8 @@ func TestUintParam(t *testing.T) {
{"baz", 0, "http://localhost?baz=0"},
}
ctx := api.NewContext()
for _, item := range table {
c := NewOrDie(ctx, "localhost", "", nil)
c := NewOrDie(&Config{})
r := c.Get().AbsPath("").UintParam(item.name, item.testVal)
if e, a := item.expectStr, r.finalURL(); e != a {
t.Errorf("expected %v, got %v", e, a)
@@ -273,9 +261,9 @@ func TestUnacceptableParamNames(t *testing.T) {
{"sync", "foo", false},
{"timeout", "42", false},
}
ctx := api.NewContext()
for _, item := range table {
c := NewOrDie(ctx, "localhost", "", nil)
c := NewOrDie(&Config{})
r := c.Get().setParam(item.name, item.testVal)
if e, a := item.expectSuccess, r.err == nil; e != a {
t.Errorf("expected %v, got %v (%v)", e, a, r.err)
@@ -284,8 +272,7 @@ func TestUnacceptableParamNames(t *testing.T) {
}
func TestSetPollPeriod(t *testing.T) {
ctx := api.NewContext()
c := NewOrDie(ctx, "localhost", "", nil)
c := NewOrDie(&Config{})
r := c.Get()
if r.pollPeriod == 0 {
t.Errorf("polling should be on by default")
@@ -315,9 +302,7 @@ func TestPolling(t *testing.T) {
w.Write(data)
}))
auth := AuthInfo{User: "user", Password: "pass"}
ctx := api.NewContext()
c := NewOrDie(ctx, testServer.URL, "v1beta1", &auth)
c := NewOrDie(&Config{Host: testServer.URL, Version: "v1beta1", Username: "user", Password: "pass"})
trials := []func(){
func() {
@@ -342,7 +327,7 @@ func TestPolling(t *testing.T) {
t.Errorf("Unexpected non error: %v", obj)
return
}
if se, ok := err.(*StatusErr); !ok || se.Status.Status != api.StatusWorking {
if se, ok := err.(APIStatus); !ok || se.Status().Status != api.StatusWorking {
t.Errorf("Unexpected kind of error: %#v", err)
return
}
@@ -357,7 +342,7 @@ func TestPolling(t *testing.T) {
}
}
func authFromReq(r *http.Request) (*AuthInfo, bool) {
func authFromReq(r *http.Request) (*Config, bool) {
auth, ok := r.Header["Authorization"]
if !ok {
return nil, false
@@ -376,16 +361,16 @@ func authFromReq(r *http.Request) (*AuthInfo, bool) {
if len(parts) != 2 {
return nil, false
}
return &AuthInfo{User: parts[0], Password: parts[1]}, true
return &Config{Username: parts[0], Password: parts[1]}, true
}
// checkAuth sets errors if the auth found in r doesn't match the expectation.
// TODO: Move to util, test in more places.
func checkAuth(t *testing.T, expect AuthInfo, r *http.Request) {
func checkAuth(t *testing.T, expect *Config, r *http.Request) {
foundAuth, found := authFromReq(r)
if !found {
t.Errorf("no auth found")
} else if e, a := expect, *foundAuth; !reflect.DeepEqual(e, a) {
} else if e, a := expect, foundAuth; !reflect.DeepEqual(e, a) {
t.Fatalf("Wrong basic auth: wanted %#v, got %#v", e, a)
}
}
@@ -400,7 +385,7 @@ func TestWatch(t *testing.T) {
{watch.Deleted, &api.Pod{JSONBase: api.JSONBase{ID: "last"}}},
}
auth := AuthInfo{User: "user", Password: "pass"}
auth := &Config{Username: "user", Password: "pass"}
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
checkAuth(t, auth, r)
flusher, ok := w.(http.Flusher)
@@ -421,8 +406,12 @@ func TestWatch(t *testing.T) {
}
}))
ctx := api.NewContext()
s, err := New(ctx, testServer.URL, "v1beta1", &auth)
s, err := New(&Config{
Host: testServer.URL,
Version: "v1beta1",
Username: "user",
Password: "pass",
})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}