func doServiceAccountAPIRequests(t *testing.T, c *client.Client, ns string, authenticated bool, canRead bool, canWrite bool) { testSecret := &api.Secret{ ObjectMeta: api.ObjectMeta{Name: "testSecret"}, Data: map[string][]byte{"test": []byte("data")}, } readOps := []testOperation{ func() error { _, err := c.Secrets(ns).List(labels.Everything(), fields.Everything()); return err }, func() error { _, err := c.Pods(ns).List(labels.Everything(), fields.Everything()); return err }, } writeOps := []testOperation{ func() error { _, err := c.Secrets(ns).Create(testSecret); return err }, func() error { return c.Secrets(ns).Delete(testSecret.Name) }, } for _, op := range readOps { err := op() unauthorizedError := errors.IsUnauthorized(err) forbiddenError := errors.IsForbidden(err) switch { case !authenticated && !unauthorizedError: t.Fatalf("expected unauthorized error, got %v", err) case authenticated && unauthorizedError: t.Fatalf("unexpected unauthorized error: %v", err) case authenticated && canRead && forbiddenError: t.Fatalf("unexpected forbidden error: %v", err) case authenticated && !canRead && !forbiddenError: t.Fatalf("expected forbidden error, got: %v", err) } } for _, op := range writeOps { err := op() unauthorizedError := errors.IsUnauthorized(err) forbiddenError := errors.IsForbidden(err) switch { case !authenticated && !unauthorizedError: t.Fatalf("expected unauthorized error, got %v", err) case authenticated && unauthorizedError: t.Fatalf("unexpected unauthorized error: %v", err) case authenticated && canWrite && forbiddenError: t.Fatalf("unexpected forbidden error: %v", err) case authenticated && !canWrite && !forbiddenError: t.Fatalf("expected forbidden error, got: %v", err) } } }
func TestErrors(t *testing.T) { o := NewObjects(api.Scheme, api.Scheme) o.Add(&api.List{ Items: []runtime.Object{ // This first call to List will return this error &(errors.NewNotFound("ServiceList", "").(*errors.StatusError).ErrStatus), // The second call to List will return this error &(errors.NewForbidden("ServiceList", "", nil).(*errors.StatusError).ErrStatus), }, }) client := &Fake{ReactFn: ObjectReaction(o, latest.RESTMapper)} _, err := client.Services("test").List(labels.Everything()) if !errors.IsNotFound(err) { t.Fatalf("unexpected error: %v", err) } t.Logf("error: %#v", err.(*errors.StatusError).Status()) _, err = client.Services("test").List(labels.Everything()) if !errors.IsForbidden(err) { t.Fatalf("unexpected error: %v", err) } }
// NewForbidden is a utility function to return a well-formatted admission control error response func NewForbidden(a Attributes, internalError error) error { // do not double wrap an error of same type if apierrors.IsForbidden(internalError) { return internalError } name := "Unknown" kind := a.GetKind() obj := a.GetObject() if obj != nil { objectMeta, err := api.ObjectMetaFor(obj) if err != nil { return apierrors.NewForbidden(kind, name, internalError) } // this is necessary because name object name generation has not occurred yet if len(objectMeta.Name) > 0 { name = objectMeta.Name } else if len(objectMeta.GenerateName) > 0 { name = objectMeta.GenerateName } } return apierrors.NewForbidden(kind, name, internalError) }
func TestRequestWatch(t *testing.T) { testCases := []struct { Request *Request Err bool ErrFn func(error) bool Empty bool }{ { Request: &Request{err: errors.New("bail")}, Err: true, }, { Request: &Request{baseURL: &url.URL{}, path: "%"}, Err: true, }, { Request: &Request{ client: clientFunc(func(req *http.Request) (*http.Response, error) { return nil, errors.New("err") }), baseURL: &url.URL{}, }, Err: true, }, { Request: &Request{ codec: testapi.Codec(), client: clientFunc(func(req *http.Request) (*http.Response, error) { return &http.Response{StatusCode: http.StatusForbidden}, nil }), baseURL: &url.URL{}, }, Err: true, ErrFn: func(err error) bool { return apierrors.IsForbidden(err) }, }, { Request: &Request{ codec: testapi.Codec(), client: clientFunc(func(req *http.Request) (*http.Response, error) { return &http.Response{StatusCode: http.StatusUnauthorized}, nil }), baseURL: &url.URL{}, }, Err: true, ErrFn: func(err error) bool { return apierrors.IsUnauthorized(err) }, }, { Request: &Request{ codec: testapi.Codec(), client: clientFunc(func(req *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusUnauthorized, Body: ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(testapi.Codec(), &api.Status{ Status: api.StatusFailure, Reason: api.StatusReasonUnauthorized, })))), }, nil }), baseURL: &url.URL{}, }, Err: true, ErrFn: func(err error) bool { return apierrors.IsUnauthorized(err) }, }, { Request: &Request{ client: clientFunc(func(req *http.Request) (*http.Response, error) { return nil, io.EOF }), baseURL: &url.URL{}, }, Empty: true, }, { Request: &Request{ client: clientFunc(func(req *http.Request) (*http.Response, error) { return nil, &url.Error{Err: io.EOF} }), baseURL: &url.URL{}, }, Empty: true, }, { Request: &Request{ client: clientFunc(func(req *http.Request) (*http.Response, error) { return nil, errors.New("http: can't write HTTP request on broken connection") }), baseURL: &url.URL{}, }, Empty: true, }, { Request: &Request{ client: clientFunc(func(req *http.Request) (*http.Response, error) { return nil, errors.New("foo: connection reset by peer") }), baseURL: &url.URL{}, }, Empty: true, }, } for i, testCase := range testCases { watch, err := testCase.Request.Watch() hasErr := err != nil if hasErr != testCase.Err { t.Errorf("%d: expected %t, got %t: %v", i, testCase.Err, hasErr, err) continue } if testCase.ErrFn != nil && !testCase.ErrFn(err) { t.Errorf("%d: error not valid: %v", i, err) } if hasErr && watch != nil { t.Errorf("%d: watch should be nil when error is returned", i) continue } if testCase.Empty { _, ok := <-watch.ResultChan() if ok { t.Errorf("%d: expected the watch to be empty: %#v", i, watch) } } } }