refactor: Add request method constants

This avoids linter errors from using inline strings as http request
methods.

Kubernetes-commit: e81887276c65acccc5486f2ff69d8bc54ac3c6ca
This commit is contained in:
Karl Isenberg 2025-04-29 16:45:30 -07:00 committed by Kubernetes Publisher
parent 93c8ec73c8
commit 61451f57b1
24 changed files with 497 additions and 436 deletions

View File

@ -567,7 +567,7 @@ func (s *ConnecterRESTStorage) Connect(ctx context.Context, id string, options r
}
func (s *ConnecterRESTStorage) ConnectMethods() []string {
return []string{"GET", "POST", "PUT", "DELETE"}
return []string{request.MethodGet, request.MethodPost, request.MethodPut, request.MethodDelete}
}
func (s *ConnecterRESTStorage) NewConnectOptions() (runtime.Object, bool, string) {
@ -741,64 +741,64 @@ func TestNotFound(t *testing.T) {
}
cases := map[string]T{
// Positive checks to make sure everything is wired correctly
"groupless GET root": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots", http.StatusOK},
"groupless GET namespaced": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples", http.StatusOK},
"groupless GET root": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots", http.StatusOK},
"groupless GET namespaced": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples", http.StatusOK},
"groupless GET long prefix": {"GET", "/" + grouplessPrefix + "/", http.StatusNotFound},
"groupless GET long prefix": {request.MethodGet, "/" + grouplessPrefix + "/", http.StatusNotFound},
"groupless root PATCH method": {"PATCH", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"groupless root GET missing storage": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/blah", http.StatusNotFound},
"groupless root GET with extra segment": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
"groupless root DELETE without extra segment": {"DELETE", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"groupless root DELETE with extra segment": {"DELETE", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
"groupless root PUT without extra segment": {"PUT", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"groupless root PUT with extra segment": {"PUT", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
"groupless root watch missing storage": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/watch/", http.StatusInternalServerError},
"groupless root PATCH method": {request.MethodPatch, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"groupless root GET missing storage": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/blah", http.StatusNotFound},
"groupless root GET with extra segment": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
"groupless root DELETE without extra segment": {request.MethodDelete, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"groupless root DELETE with extra segment": {request.MethodDelete, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
"groupless root PUT without extra segment": {request.MethodPut, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"groupless root PUT with extra segment": {request.MethodPut, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
"groupless root watch missing storage": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/watch/", http.StatusInternalServerError},
"groupless namespaced PATCH method": {"PATCH", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"groupless namespaced GET long prefix": {"GET", "/" + grouplessPrefix + "/", http.StatusNotFound},
"groupless namespaced GET missing storage": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/blah", http.StatusNotFound},
"groupless namespaced GET with extra segment": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"groupless namespaced POST with extra segment": {"POST", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples/bar", http.StatusMethodNotAllowed},
"groupless namespaced DELETE without extra segment": {"DELETE", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"groupless namespaced DELETE with extra segment": {"DELETE", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"groupless namespaced PUT without extra segment": {"PUT", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"groupless namespaced PUT with extra segment": {"PUT", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"groupless namespaced watch missing storage": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/watch/", http.StatusInternalServerError},
"groupless namespaced watch with bad method": {"POST", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/watch/namespaces/ns/simples/bar", http.StatusMethodNotAllowed},
"groupless namespaced watch param with bad method": {"POST", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples/bar?watch=true", http.StatusMethodNotAllowed},
"groupless namespaced PATCH method": {request.MethodPatch, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"groupless namespaced GET long prefix": {request.MethodGet, "/" + grouplessPrefix + "/", http.StatusNotFound},
"groupless namespaced GET missing storage": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/blah", http.StatusNotFound},
"groupless namespaced GET with extra segment": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"groupless namespaced POST with extra segment": {request.MethodPost, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples/bar", http.StatusMethodNotAllowed},
"groupless namespaced DELETE without extra segment": {request.MethodDelete, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"groupless namespaced DELETE with extra segment": {request.MethodDelete, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"groupless namespaced PUT without extra segment": {request.MethodPut, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"groupless namespaced PUT with extra segment": {request.MethodPut, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"groupless namespaced watch missing storage": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/watch/", http.StatusInternalServerError},
"groupless namespaced watch with bad method": {request.MethodPost, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/watch/namespaces/ns/simples/bar", http.StatusMethodNotAllowed},
"groupless namespaced watch param with bad method": {request.MethodPost, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/ns/simples/bar?watch=true", http.StatusMethodNotAllowed},
// Positive checks to make sure everything is wired correctly
"GET root": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusOK},
// TODO: JTL: "GET root item": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar", http.StatusOK},
"GET namespaced": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusOK},
// TODO: JTL: "GET namespaced item": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar", http.StatusOK},
"GET root": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusOK},
// TODO: JTL: "GET root item": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar", http.StatusOK},
"GET namespaced": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusOK},
// TODO: JTL: "GET namespaced item": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar", http.StatusOK},
"GET long prefix": {"GET", "/" + prefix + "/", http.StatusNotFound},
"GET long prefix": {request.MethodGet, "/" + prefix + "/", http.StatusNotFound},
"root PATCH method": {"PATCH", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"root GET missing storage": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/blah", http.StatusNotFound},
"root GET with extra segment": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
// TODO: JTL: "root POST with extra segment": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar", http.StatusMethodNotAllowed},
"root DELETE without extra segment": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"root DELETE with extra segment": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
"root PUT without extra segment": {"PUT", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"root PUT with extra segment": {"PUT", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
"root watch missing storage": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/", http.StatusInternalServerError},
// TODO: JTL: "root watch with bad method": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simpleroot/bar", http.StatusMethodNotAllowed},
"root PATCH method": {request.MethodPatch, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"root GET missing storage": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/blah", http.StatusNotFound},
"root GET with extra segment": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
// TODO: JTL: "root POST with extra segment": {request.MethodPost, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar", http.StatusMethodNotAllowed},
"root DELETE without extra segment": {request.MethodDelete, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"root DELETE with extra segment": {request.MethodDelete, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
"root PUT without extra segment": {request.MethodPut, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed},
"root PUT with extra segment": {request.MethodPut, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound},
"root watch missing storage": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/", http.StatusInternalServerError},
// TODO: JTL: "root watch with bad method": {request.MethodPost, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simpleroot/bar", http.StatusMethodNotAllowed},
"namespaced PATCH method": {"PATCH", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"namespaced GET long prefix": {"GET", "/" + prefix + "/", http.StatusNotFound},
"namespaced GET missing storage": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/blah", http.StatusNotFound},
"namespaced GET with extra segment": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"namespaced POST with extra segment": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar", http.StatusMethodNotAllowed},
"namespaced DELETE without extra segment": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"namespaced DELETE with extra segment": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"namespaced PUT without extra segment": {"PUT", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"namespaced PUT with extra segment": {"PUT", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"namespaced watch missing storage": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/", http.StatusInternalServerError},
"namespaced watch with bad method": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/namespaces/ns/simples/bar", http.StatusMethodNotAllowed},
"namespaced watch param with bad method": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar?watch=true", http.StatusMethodNotAllowed},
"namespaced PATCH method": {request.MethodPatch, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"namespaced GET long prefix": {request.MethodGet, "/" + prefix + "/", http.StatusNotFound},
"namespaced GET missing storage": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/blah", http.StatusNotFound},
"namespaced GET with extra segment": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"namespaced POST with extra segment": {request.MethodPost, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar", http.StatusMethodNotAllowed},
"namespaced DELETE without extra segment": {request.MethodDelete, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"namespaced DELETE with extra segment": {request.MethodDelete, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"namespaced PUT without extra segment": {request.MethodPut, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed},
"namespaced PUT with extra segment": {request.MethodPut, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound},
"namespaced watch missing storage": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/", http.StatusInternalServerError},
"namespaced watch with bad method": {request.MethodPost, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/namespaces/ns/simples/bar", http.StatusMethodNotAllowed},
"namespaced watch param with bad method": {request.MethodPost, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar?watch=true", http.StatusMethodNotAllowed},
}
handler := handle(map[string]rest.Storage{
"simples": &SimpleRESTStorage{},
@ -853,23 +853,23 @@ func TestUnimplementedRESTStorage(t *testing.T) {
ErrCode int
}
cases := map[string]T{
"groupless GET object": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"groupless GET list": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/foo", http.StatusNotFound},
"groupless POST list": {"POST", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/foo", http.StatusNotFound},
"groupless PUT object": {"PUT", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"groupless DELETE object": {"DELETE", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"groupless watch list": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/watch/foo", http.StatusNotFound},
"groupless watch object": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/watch/foo/bar", http.StatusNotFound},
"groupless proxy object": {"GET", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/proxy/foo/bar", http.StatusNotFound},
"groupless GET object": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"groupless GET list": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/foo", http.StatusNotFound},
"groupless POST list": {request.MethodPost, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/foo", http.StatusNotFound},
"groupless PUT object": {request.MethodPut, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"groupless DELETE object": {request.MethodDelete, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"groupless watch list": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/watch/foo", http.StatusNotFound},
"groupless watch object": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/watch/foo/bar", http.StatusNotFound},
"groupless proxy object": {request.MethodGet, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/proxy/foo/bar", http.StatusNotFound},
"GET object": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"GET list": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo", http.StatusNotFound},
"POST list": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo", http.StatusNotFound},
"PUT object": {"PUT", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"DELETE object": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"watch list": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/foo", http.StatusNotFound},
"watch object": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/foo/bar", http.StatusNotFound},
"proxy object": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/proxy/foo/bar", http.StatusNotFound},
"GET object": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"GET list": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo", http.StatusNotFound},
"POST list": {request.MethodPost, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo", http.StatusNotFound},
"PUT object": {request.MethodPut, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"DELETE object": {request.MethodDelete, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo/bar", http.StatusNotFound},
"watch list": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/foo", http.StatusNotFound},
"watch object": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/foo/bar", http.StatusNotFound},
"proxy object": {request.MethodGet, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/proxy/foo/bar", http.StatusNotFound},
}
handler := handle(map[string]rest.Storage{
"foo": UnimplementedRESTStorage{},
@ -931,14 +931,14 @@ func TestSomeUnimplementedRESTStorage(t *testing.T) {
}
cases := map[string]T{
"groupless POST list": {"POST", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/foo", http.StatusMethodNotAllowed},
"groupless PUT object": {"PUT", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/foo/bar", http.StatusMethodNotAllowed},
"groupless DELETE object": {"DELETE", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/foo/bar", http.StatusMethodNotAllowed},
"groupless DELETE collection": {"DELETE", "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/foo", http.StatusMethodNotAllowed},
"POST list": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo", http.StatusMethodNotAllowed},
"PUT object": {"PUT", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo/bar", http.StatusMethodNotAllowed},
"DELETE object": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo/bar", http.StatusMethodNotAllowed},
"DELETE collection": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo", http.StatusMethodNotAllowed},
"groupless POST list": {request.MethodPost, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/foo", http.StatusMethodNotAllowed},
"groupless PUT object": {request.MethodPut, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/foo/bar", http.StatusMethodNotAllowed},
"groupless DELETE object": {request.MethodDelete, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/foo/bar", http.StatusMethodNotAllowed},
"groupless DELETE collection": {request.MethodDelete, "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default/foo", http.StatusMethodNotAllowed},
"POST list": {request.MethodPost, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo", http.StatusMethodNotAllowed},
"PUT object": {request.MethodPut, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo/bar", http.StatusMethodNotAllowed},
"DELETE object": {request.MethodDelete, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo/bar", http.StatusMethodNotAllowed},
"DELETE collection": {request.MethodDelete, "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo", http.StatusMethodNotAllowed},
}
handler := handle(map[string]rest.Storage{
"foo": OnlyGetRESTStorage{},
@ -1158,12 +1158,12 @@ func TestRequestsWithInvalidQuery(t *testing.T) {
postfix string
method string
}{
{"/simple?labelSelector=<invalid>", http.MethodGet},
{"/simple/foo?gracePeriodSeconds=<invalid>", http.MethodDelete},
// {"/simple?labelSelector=<value>", http.MethodDelete}, TODO: implement DeleteCollection in SimpleRESTStorage
// {"/simple/foo?export=<invalid>", http.MethodGet}, TODO: there is no invalid bool in conversion. Should we be more strict?
// {"/simple/foo?resourceVersion=<invalid>", http.MethodGet}, TODO: there is no invalid resourceVersion. Should we be more strict?
// {"/withoptions?labelSelector=<invalid>", http.MethodGet}, TODO: SimpleGetOptions is always valid. Add more validation that can fail.
{"/simple?labelSelector=<invalid>", request.MethodGet},
{"/simple/foo?gracePeriodSeconds=<invalid>", request.MethodDelete},
// {"/simple?labelSelector=<value>", request.MethodDelete}, TODO: implement DeleteCollection in SimpleRESTStorage
// {"/simple/foo?export=<invalid>", request.MethodGet}, TODO: there is no invalid bool in conversion. Should we be more strict?
// {"/simple/foo?resourceVersion=<invalid>", request.MethodGet}, TODO: there is no invalid resourceVersion. Should we be more strict?
// {"/withoptions?labelSelector=<invalid>", request.MethodGet}, TODO: SimpleGetOptions is always valid. Add more validation that can fail.
} {
baseURL := server.URL + "/" + grouplessPrefix + "/" + grouplessGroupVersion.Version + "/namespaces/default"
url := baseURL + test.postfix
@ -1228,7 +1228,7 @@ func TestListCompression(t *testing.T) {
defer server.Close()
req, err := http.NewRequest("GET", server.URL+testCase.url, nil)
req, err := http.NewRequest(request.MethodGet, server.URL+testCase.url, nil)
if err != nil {
t.Errorf("%d: unexpected error: %v", i, err)
continue
@ -1289,7 +1289,7 @@ func TestLogs(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("GET", server.URL+"/logs", nil)
request, err := http.NewRequest(request.MethodGet, server.URL+"/logs", nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -1526,7 +1526,7 @@ func TestGetCompression(t *testing.T) {
}
for _, test := range tests {
req, err := http.NewRequest("GET", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/id", nil)
req, err := http.NewRequest(request.MethodGet, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/id", nil)
if err != nil {
t.Fatalf("unexpected error creating request: %v", err)
}
@ -1603,7 +1603,7 @@ func TestGetPretty(t *testing.T) {
t.Fatal(err)
}
u.RawQuery = test.params.Encode()
req := &http.Request{Method: "GET", URL: u}
req := &http.Request{Method: request.MethodGet, URL: u}
req.Header = http.Header{}
req.Header.Set("Accept", test.accept)
req.Header.Set("User-Agent", test.userAgent)
@ -1802,7 +1802,7 @@ func TestGetTable(t *testing.T) {
t.Fatal(err)
}
u.RawQuery = test.params.Encode()
req := &http.Request{Method: "GET", URL: u}
req := &http.Request{Method: request.MethodGet, URL: u}
req.Header = http.Header{}
req.Header.Set("Accept", test.accept)
resp, err := http.DefaultClient.Do(req)
@ -2012,7 +2012,7 @@ func TestWatchTable(t *testing.T) {
test.params["watch"] = []string{"1"}
u.RawQuery = test.params.Encode()
req := &http.Request{Method: "GET", URL: u}
req := &http.Request{Method: request.MethodGet, URL: u}
req.Header = http.Header{}
req.Header.Set("Accept", test.accept)
resp, err := http.DefaultClient.Do(req)
@ -2207,7 +2207,7 @@ func TestGetPartialObjectMetadata(t *testing.T) {
t.Fatal(err)
}
u.RawQuery = test.params.Encode()
req := &http.Request{Method: "GET", URL: u}
req := &http.Request{Method: request.MethodGet, URL: u}
req.Header = http.Header{}
req.Header.Set("Accept", test.accept)
resp, err := http.DefaultClient.Do(req)
@ -2271,7 +2271,7 @@ func TestGetBinary(t *testing.T) {
server := httptest.NewServer(handle(map[string]rest.Storage{"simple": &simpleStorage}))
defer server.Close()
req, err := http.NewRequest("GET", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/binary", nil)
req, err := http.NewRequest(request.MethodGet, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/binary", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -2327,7 +2327,7 @@ func TestGetWithOptionsRouteParams(t *testing.T) {
}
routes := ws[0].Routes()
for i := range routes {
if routes[i].Method == "GET" && routes[i].Operation == "readNamespacedSimple" {
if routes[i].Method == request.MethodGet && routes[i].Operation == "readNamespacedSimple" {
validateSimpleGetOptionsParams(t, &routes[i])
break
}
@ -2768,7 +2768,7 @@ func TestDelete(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil)
request, err := http.NewRequest(request.MethodDelete, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2803,7 +2803,7 @@ func TestDeleteWithOptions(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest(request.MethodDelete, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2843,7 +2843,7 @@ func TestDeleteWithOptionsQuery(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID+"?gracePeriodSeconds="+strconv.FormatInt(grace, 10), nil)
request, err := http.NewRequest(request.MethodDelete, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID+"?gracePeriodSeconds="+strconv.FormatInt(grace, 10), nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2886,7 +2886,7 @@ func TestDeleteWithOptionsQueryAndBody(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID+"?gracePeriodSeconds="+strconv.FormatInt(grace+10, 10), bytes.NewReader(body))
request, err := http.NewRequest(request.MethodDelete, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID+"?gracePeriodSeconds="+strconv.FormatInt(grace+10, 10), bytes.NewReader(body))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2925,7 +2925,7 @@ func TestDeleteInvokesAdmissionControl(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil)
request, err := http.NewRequest(request.MethodDelete, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2951,7 +2951,7 @@ func TestDeleteMissing(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil)
request, err := http.NewRequest(request.MethodDelete, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2988,7 +2988,7 @@ func TestUpdate(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest(request.MethodPut, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3030,7 +3030,7 @@ func TestUpdateInvokesAdmissionControl(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest(request.MethodPut, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3066,7 +3066,7 @@ func TestUpdateRequiresMatchingName(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest(request.MethodPut, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3103,7 +3103,7 @@ func TestUpdateAllowsMissingNamespace(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest(request.MethodPut, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3143,7 +3143,7 @@ func TestUpdateDisallowsMismatchedNamespaceOnError(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest(request.MethodPut, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3182,7 +3182,7 @@ func TestUpdatePreventsMismatchedNamespace(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest(request.MethodPut, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3219,7 +3219,7 @@ func TestUpdateMissing(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest(request.MethodPut, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3249,7 +3249,7 @@ func TestCreateNotFound(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3275,7 +3275,7 @@ func TestCreateChecksDecode(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3363,14 +3363,14 @@ func TestParentResourceIsRequired(t *testing.T) {
// resource is NOT registered in the root scope
w := httptest.NewRecorder()
handler.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/" + prefix + "/simple/test/sub"}})
handler.ServeHTTP(w, &http.Request{Method: request.MethodGet, URL: &url.URL{Path: "/" + prefix + "/simple/test/sub"}})
if w.Code != http.StatusNotFound {
t.Errorf("expected not found: %#v", w)
}
// resource is registered in the namespace scope
w = httptest.NewRecorder()
handler.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/test/simple/test/sub"}})
handler.ServeHTTP(w, &http.Request{Method: request.MethodGet, URL: &url.URL{Path: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/test/simple/test/sub"}})
if w.Code != http.StatusOK {
t.Fatalf("expected OK: %#v", w)
}
@ -3395,7 +3395,7 @@ func TestNamedCreaterWithName(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+pathName+"/sub", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+pathName+"/sub", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3433,7 +3433,7 @@ func TestNamedCreaterWithoutName(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3507,7 +3507,7 @@ func TestNamedCreaterWithGenerateName(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3554,7 +3554,7 @@ func TestUpdateChecksDecode(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/bar", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPut, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/bar", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3592,7 +3592,7 @@ func TestCreate(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3654,7 +3654,7 @@ func TestCreateYAML(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo", bytes.NewBuffer(data))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -3710,7 +3710,7 @@ func TestCreateInNamespace(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/foo", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/foo", bytes.NewBuffer(data))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -3767,7 +3767,7 @@ func TestCreateInvokeAdmissionControl(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/foo", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/foo", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3818,7 +3818,7 @@ func TestDelayReturnsError(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
status := expectAPIStatus(t, "DELETE", fmt.Sprintf("%s/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo/bar", server.URL), nil, http.StatusConflict)
status := expectAPIStatus(t, request.MethodDelete, fmt.Sprintf("%s/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo/bar", server.URL), nil, http.StatusConflict)
if status.Status != metav1.StatusFailure || status.Message == "" || status.Details == nil || status.Reason != metav1.StatusReasonAlreadyExists {
t.Errorf("Unexpected status %#v", status)
}
@ -3849,7 +3849,7 @@ func TestWriteJSONDecodeError(t *testing.T) {
// Unless specific metav1.Status() parameters are implemented for the particular error in question, such that
// the status code is defined, metav1 errors where error.status == metav1.StatusFailure
// will throw a '500 Internal Server Error'. Non-metav1 type errors will always throw a '500 Internal Server Error'.
status := expectAPIStatus(t, "GET", server.URL, nil, http.StatusInternalServerError)
status := expectAPIStatus(t, request.MethodGet, server.URL, nil, http.StatusInternalServerError)
if status.Reason != metav1.StatusReasonUnknown {
t.Errorf("unexpected reason %#v", status)
}
@ -3903,7 +3903,7 @@ func TestCreateTimeout(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
itemOut := expectAPIStatus(t, "POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo?timeout=4ms", data, http.StatusGatewayTimeout)
itemOut := expectAPIStatus(t, request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo?timeout=4ms", data, http.StatusGatewayTimeout)
if itemOut.Status != metav1.StatusFailure || itemOut.Reason != metav1.StatusReasonTimeout {
t.Errorf("Unexpected status %#v", itemOut)
}
@ -3921,7 +3921,7 @@ func TestCreateChecksAPIVersion(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3962,7 +3962,7 @@ func TestCreateDefaultsAPIVersion(t *testing.T) {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPost, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -3986,7 +3986,7 @@ func TestUpdateChecksAPIVersion(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/bar", bytes.NewBuffer(data))
request, err := http.NewRequest(request.MethodPut, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/bar", bytes.NewBuffer(data))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -4094,37 +4094,37 @@ unknown: baz`)
expectedStatusCode int
}{
// Create
{name: "post-strict-validation", path: "/namespaces/default/simples", verb: "POST", data: invalidJSONDataPost, queryParams: strictFieldValidation, expectedStatusCode: http.StatusBadRequest, expectedErr: strictDecodingErr},
{name: "post-warn-validation", path: "/namespaces/default/simples", verb: "POST", data: invalidJSONDataPost, queryParams: warnFieldValidation, expectedStatusCode: http.StatusCreated, expectedWarns: strictDecodingWarns},
{name: "post-ignore-validation", path: "/namespaces/default/simples", verb: "POST", data: invalidJSONDataPost, queryParams: ignoreFieldValidation, expectedStatusCode: http.StatusCreated},
{name: "post-strict-validation", path: "/namespaces/default/simples", verb: request.MethodPost, data: invalidJSONDataPost, queryParams: strictFieldValidation, expectedStatusCode: http.StatusBadRequest, expectedErr: strictDecodingErr},
{name: "post-warn-validation", path: "/namespaces/default/simples", verb: request.MethodPost, data: invalidJSONDataPost, queryParams: warnFieldValidation, expectedStatusCode: http.StatusCreated, expectedWarns: strictDecodingWarns},
{name: "post-ignore-validation", path: "/namespaces/default/simples", verb: request.MethodPost, data: invalidJSONDataPost, queryParams: ignoreFieldValidation, expectedStatusCode: http.StatusCreated},
{name: "post-strict-validation-yaml", path: "/namespaces/default/simples", verb: "POST", data: invalidYAMLDataPost, queryParams: strictFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusBadRequest, expectedErr: strictDecodingErrYAML},
{name: "post-warn-validation-yaml", path: "/namespaces/default/simples", verb: "POST", data: invalidYAMLDataPost, queryParams: warnFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusCreated, expectedWarns: strictDecodingWarnsYAML},
{name: "post-ignore-validation-yaml", path: "/namespaces/default/simples", verb: "POST", data: invalidYAMLDataPost, queryParams: ignoreFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusCreated},
{name: "post-strict-validation-yaml", path: "/namespaces/default/simples", verb: request.MethodPost, data: invalidYAMLDataPost, queryParams: strictFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusBadRequest, expectedErr: strictDecodingErrYAML},
{name: "post-warn-validation-yaml", path: "/namespaces/default/simples", verb: request.MethodPost, data: invalidYAMLDataPost, queryParams: warnFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusCreated, expectedWarns: strictDecodingWarnsYAML},
{name: "post-ignore-validation-yaml", path: "/namespaces/default/simples", verb: request.MethodPost, data: invalidYAMLDataPost, queryParams: ignoreFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusCreated},
// Update
{name: "put-strict-validation", path: "/namespaces/default/simples/id", verb: "PUT", data: invalidJSONDataPut, queryParams: strictFieldValidation, expectedStatusCode: http.StatusBadRequest, expectedErr: strictDecodingErr},
{name: "put-warn-validation", path: "/namespaces/default/simples/id", verb: "PUT", data: invalidJSONDataPut, queryParams: warnFieldValidation, expectedStatusCode: http.StatusOK, expectedWarns: strictDecodingWarns},
{name: "put-ignore-validation", path: "/namespaces/default/simples/id", verb: "PUT", data: invalidJSONDataPut, queryParams: ignoreFieldValidation, expectedStatusCode: http.StatusOK},
{name: "put-strict-validation", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: invalidJSONDataPut, queryParams: strictFieldValidation, expectedStatusCode: http.StatusBadRequest, expectedErr: strictDecodingErr},
{name: "put-warn-validation", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: invalidJSONDataPut, queryParams: warnFieldValidation, expectedStatusCode: http.StatusOK, expectedWarns: strictDecodingWarns},
{name: "put-ignore-validation", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: invalidJSONDataPut, queryParams: ignoreFieldValidation, expectedStatusCode: http.StatusOK},
{name: "put-strict-validation-yaml", path: "/namespaces/default/simples/id", verb: "PUT", data: invalidYAMLDataPut, queryParams: strictFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusBadRequest, expectedErr: strictDecodingErrYAMLPut},
{name: "put-warn-validation-yaml", path: "/namespaces/default/simples/id", verb: "PUT", data: invalidYAMLDataPut, queryParams: warnFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusOK, expectedWarns: strictDecodingWarnsYAMLPut},
{name: "put-ignore-validation-yaml", path: "/namespaces/default/simples/id", verb: "PUT", data: invalidYAMLDataPut, queryParams: ignoreFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusOK},
{name: "put-strict-validation-yaml", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: invalidYAMLDataPut, queryParams: strictFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusBadRequest, expectedErr: strictDecodingErrYAMLPut},
{name: "put-warn-validation-yaml", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: invalidYAMLDataPut, queryParams: warnFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusOK, expectedWarns: strictDecodingWarnsYAMLPut},
{name: "put-ignore-validation-yaml", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: invalidYAMLDataPut, queryParams: ignoreFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusOK},
// MergePatch
{name: "merge-patch-strict-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: invalidMergePatch, queryParams: strictFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusUnprocessableEntity, expectedErr: strictDecodingErr},
{name: "merge-patch-warn-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: invalidMergePatch, queryParams: warnFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK, expectedWarns: strictDecodingWarns},
{name: "merge-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: invalidMergePatch, queryParams: ignoreFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "merge-patch-strict-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: invalidMergePatch, queryParams: strictFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusUnprocessableEntity, expectedErr: strictDecodingErr},
{name: "merge-patch-warn-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: invalidMergePatch, queryParams: warnFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK, expectedWarns: strictDecodingWarns},
{name: "merge-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: invalidMergePatch, queryParams: ignoreFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
// JSON Patch
{name: "json-patch-strict-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: invalidJSONPatch, queryParams: strictFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusUnprocessableEntity, expectedErr: jsonPatchStrictDecodingErr},
{name: "json-patch-warn-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: invalidJSONPatch, queryParams: warnFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK, expectedWarns: jsonPatchStrictDecodingWarns},
{name: "json-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: invalidJSONPatch, queryParams: ignoreFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "json-patch-strict-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: invalidJSONPatch, queryParams: strictFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusUnprocessableEntity, expectedErr: jsonPatchStrictDecodingErr},
{name: "json-patch-warn-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: invalidJSONPatch, queryParams: warnFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK, expectedWarns: jsonPatchStrictDecodingWarns},
{name: "json-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: invalidJSONPatch, queryParams: ignoreFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
// SMP
{name: "strategic-merge-patch-strict-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: invalidSMP, queryParams: strictFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusUnprocessableEntity, expectedErr: strictDecodingErr},
{name: "strategic-merge-patch-warn-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: invalidSMP, queryParams: warnFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK, expectedWarns: strictDecodingWarns},
{name: "strategic-merge-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: invalidSMP, queryParams: ignoreFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "strategic-merge-patch-strict-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: invalidSMP, queryParams: strictFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusUnprocessableEntity, expectedErr: strictDecodingErr},
{name: "strategic-merge-patch-warn-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: invalidSMP, queryParams: warnFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK, expectedWarns: strictDecodingWarns},
{name: "strategic-merge-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: invalidSMP, queryParams: ignoreFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
}
)
@ -4209,37 +4209,37 @@ other: bar`)
expectedStatusCode int
}{
// Create
{name: "post-strict-validation", path: "/namespaces/default/simples", verb: "POST", data: validJSONDataPost, queryParams: strictFieldValidation, expectedStatusCode: http.StatusCreated},
{name: "post-warn-validation", path: "/namespaces/default/simples", verb: "POST", data: validJSONDataPost, queryParams: warnFieldValidation, expectedStatusCode: http.StatusCreated},
{name: "post-ignore-validation", path: "/namespaces/default/simples", verb: "POST", data: validJSONDataPost, queryParams: ignoreFieldValidation, expectedStatusCode: http.StatusCreated},
{name: "post-strict-validation", path: "/namespaces/default/simples", verb: request.MethodPost, data: validJSONDataPost, queryParams: strictFieldValidation, expectedStatusCode: http.StatusCreated},
{name: "post-warn-validation", path: "/namespaces/default/simples", verb: request.MethodPost, data: validJSONDataPost, queryParams: warnFieldValidation, expectedStatusCode: http.StatusCreated},
{name: "post-ignore-validation", path: "/namespaces/default/simples", verb: request.MethodPost, data: validJSONDataPost, queryParams: ignoreFieldValidation, expectedStatusCode: http.StatusCreated},
{name: "post-strict-validation-yaml", path: "/namespaces/default/simples", verb: "POST", data: validYAMLDataPost, queryParams: strictFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusCreated},
{name: "post-warn-validation-yaml", path: "/namespaces/default/simples", verb: "POST", data: validYAMLDataPost, queryParams: warnFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusCreated},
{name: "post-ignore-validation-yaml", path: "/namespaces/default/simples", verb: "POST", data: validYAMLDataPost, queryParams: ignoreFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusCreated},
{name: "post-strict-validation-yaml", path: "/namespaces/default/simples", verb: request.MethodPost, data: validYAMLDataPost, queryParams: strictFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusCreated},
{name: "post-warn-validation-yaml", path: "/namespaces/default/simples", verb: request.MethodPost, data: validYAMLDataPost, queryParams: warnFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusCreated},
{name: "post-ignore-validation-yaml", path: "/namespaces/default/simples", verb: request.MethodPost, data: validYAMLDataPost, queryParams: ignoreFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusCreated},
// Update
{name: "put-strict-validation", path: "/namespaces/default/simples/id", verb: "PUT", data: validJSONDataPut, queryParams: strictFieldValidation, expectedStatusCode: http.StatusOK},
{name: "put-warn-validation", path: "/namespaces/default/simples/id", verb: "PUT", data: validJSONDataPut, queryParams: warnFieldValidation, expectedStatusCode: http.StatusOK},
{name: "put-ignore-validation", path: "/namespaces/default/simples/id", verb: "PUT", data: validJSONDataPut, queryParams: ignoreFieldValidation, expectedStatusCode: http.StatusOK},
{name: "put-strict-validation", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: validJSONDataPut, queryParams: strictFieldValidation, expectedStatusCode: http.StatusOK},
{name: "put-warn-validation", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: validJSONDataPut, queryParams: warnFieldValidation, expectedStatusCode: http.StatusOK},
{name: "put-ignore-validation", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: validJSONDataPut, queryParams: ignoreFieldValidation, expectedStatusCode: http.StatusOK},
{name: "put-strict-validation-yaml", path: "/namespaces/default/simples/id", verb: "PUT", data: validYAMLDataPut, queryParams: strictFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusOK},
{name: "put-warn-validation-yaml", path: "/namespaces/default/simples/id", verb: "PUT", data: validYAMLDataPut, queryParams: warnFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusOK},
{name: "put-ignore-validation-yaml", path: "/namespaces/default/simples/id", verb: "PUT", data: validYAMLDataPut, queryParams: ignoreFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusOK},
{name: "put-strict-validation-yaml", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: validYAMLDataPut, queryParams: strictFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusOK},
{name: "put-warn-validation-yaml", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: validYAMLDataPut, queryParams: warnFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusOK},
{name: "put-ignore-validation-yaml", path: "/namespaces/default/simples/id", verb: request.MethodPut, data: validYAMLDataPut, queryParams: ignoreFieldValidation, contentType: "application/yaml", expectedStatusCode: http.StatusOK},
// MergePatch
{name: "merge-patch-strict-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: validMergePatch, queryParams: strictFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "merge-patch-warn-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: validMergePatch, queryParams: warnFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "merge-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: validMergePatch, queryParams: ignoreFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "merge-patch-strict-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: validMergePatch, queryParams: strictFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "merge-patch-warn-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: validMergePatch, queryParams: warnFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "merge-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: validMergePatch, queryParams: ignoreFieldValidation, contentType: "application/merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
// JSON Patch
{name: "json-patch-strict-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: validJSONPatch, queryParams: strictFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "json-patch-warn-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: validJSONPatch, queryParams: warnFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "json-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: validJSONPatch, queryParams: ignoreFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "json-patch-strict-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: validJSONPatch, queryParams: strictFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "json-patch-warn-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: validJSONPatch, queryParams: warnFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "json-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: validJSONPatch, queryParams: ignoreFieldValidation, contentType: "application/json-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
// SMP
{name: "strategic-merge-patch-strict-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: validSMP, queryParams: strictFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "strategic-merge-patch-warn-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: validSMP, queryParams: warnFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "strategic-merge-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: "PATCH", data: validSMP, queryParams: ignoreFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "strategic-merge-patch-strict-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: validSMP, queryParams: strictFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "strategic-merge-patch-warn-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: validSMP, queryParams: warnFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
{name: "strategic-merge-patch-ignore-validation", path: "/namespaces/default/simples/id", verb: request.MethodPatch, data: validSMP, queryParams: ignoreFieldValidation, contentType: "application/strategic-merge-patch+json; charset=UTF-8", expectedStatusCode: http.StatusOK},
}
)
@ -4421,7 +4421,7 @@ func BenchmarkUpdateProtobuf(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
request, err := http.NewRequest("PUT", dest.String(), bytes.NewReader(data))
request, err := http.NewRequest(request.MethodPut, dest.String(), bytes.NewReader(data))
if err != nil {
b.Fatalf("unexpected error: %v", err)
}

View File

@ -30,6 +30,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/wait"
auditinternal "k8s.io/apiserver/pkg/apis/audit"
"k8s.io/apiserver/pkg/endpoints/request"
genericapitesting "k8s.io/apiserver/pkg/endpoints/testing"
"k8s.io/apiserver/pkg/registry/rest"
)
@ -156,7 +157,7 @@ func TestAudit(t *testing.T) {
{
"get",
func(server string) (*http.Request, error) {
return http.NewRequest("GET", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple/c", bytes.NewBuffer(simpleFooJSON))
return http.NewRequest(request.MethodGet, server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple/c", bytes.NewBuffer(simpleFooJSON))
},
200,
2,
@ -169,7 +170,7 @@ func TestAudit(t *testing.T) {
{
"list",
func(server string) (*http.Request, error) {
return http.NewRequest("GET", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple?labelSelector=a%3Dfoobar", nil)
return http.NewRequest(request.MethodGet, server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple?labelSelector=a%3Dfoobar", nil)
},
200,
2,
@ -182,7 +183,7 @@ func TestAudit(t *testing.T) {
{
"create",
func(server string) (*http.Request, error) {
return http.NewRequest("POST", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(simpleFooJSON))
return http.NewRequest(request.MethodPost, server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(simpleFooJSON))
},
201,
2,
@ -195,7 +196,7 @@ func TestAudit(t *testing.T) {
{
"not-allowed-named-create",
func(server string) (*http.Request, error) {
return http.NewRequest("POST", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/named", bytes.NewBuffer(simpleFooJSON))
return http.NewRequest(request.MethodPost, server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/named", bytes.NewBuffer(simpleFooJSON))
},
405,
2,
@ -208,7 +209,7 @@ func TestAudit(t *testing.T) {
{
"delete",
func(server string) (*http.Request, error) {
return http.NewRequest("DELETE", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/a", nil)
return http.NewRequest(request.MethodDelete, server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/a", nil)
},
200,
2,
@ -221,7 +222,7 @@ func TestAudit(t *testing.T) {
{
"delete-with-options-in-body",
func(server string) (*http.Request, error) {
return http.NewRequest("DELETE", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/a", bytes.NewBuffer([]byte(`{"kind":"DeleteOptions"}`)))
return http.NewRequest(request.MethodDelete, server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/a", bytes.NewBuffer([]byte(`{"kind":"DeleteOptions"}`)))
},
200,
2,
@ -234,7 +235,7 @@ func TestAudit(t *testing.T) {
{
"update",
func(server string) (*http.Request, error) {
return http.NewRequest("PUT", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple/c", bytes.NewBuffer(simpleCPrimeJSON))
return http.NewRequest(request.MethodPut, server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple/c", bytes.NewBuffer(simpleCPrimeJSON))
},
200,
2,
@ -247,7 +248,7 @@ func TestAudit(t *testing.T) {
{
"update-wrong-namespace",
func(server string) (*http.Request, error) {
return http.NewRequest("PUT", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/c", bytes.NewBuffer(simpleCPrimeJSON))
return http.NewRequest(request.MethodPut, server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/c", bytes.NewBuffer(simpleCPrimeJSON))
},
400,
2,
@ -260,7 +261,7 @@ func TestAudit(t *testing.T) {
{
"patch",
func(server string) (*http.Request, error) {
req, _ := http.NewRequest("PATCH", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple/c", bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`)))
req, _ := http.NewRequest(request.MethodPatch, server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple/c", bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`)))
req.Header.Set("Content-Type", "application/merge-patch+json; charset=UTF-8")
return req, nil
},
@ -275,7 +276,7 @@ func TestAudit(t *testing.T) {
{
"watch",
func(server string) (*http.Request, error) {
return http.NewRequest("GET", server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple?watch=true", nil)
return http.NewRequest(request.MethodGet, server+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/simple?watch=true", nil)
},
200,
3,

View File

@ -22,25 +22,22 @@ import (
"reflect"
"sort"
"sync"
"sync/atomic"
apidiscoveryv2 "k8s.io/api/apidiscovery/v2"
apidiscoveryv2beta1 "k8s.io/api/apidiscovery/v2beta1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/version"
apidiscoveryv2conversion "k8s.io/apiserver/pkg/apis/apidiscovery/v2"
genericfeatures "k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
"k8s.io/apiserver/pkg/endpoints/metrics"
"sync/atomic"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/version"
apidiscoveryv2conversion "k8s.io/apiserver/pkg/apis/apidiscovery/v2"
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
"k8s.io/apiserver/pkg/endpoints/handlers/responsewriters"
"k8s.io/apiserver/pkg/endpoints/metrics"
"k8s.io/apiserver/pkg/endpoints/request"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/klog/v2"
)
@ -163,7 +160,7 @@ func NewResourceManager(path string) ResourceManager {
serializer: codecs,
versionPriorities: make(map[groupVersionKey]priorityInfo),
}
rdm.serveHTTPFunc = metrics.InstrumentHandlerFunc("GET",
rdm.serveHTTPFunc = metrics.InstrumentHandlerFunc(request.MethodGet,
/* group = */ "",
/* version = */ "",
/* resource = */ "",

View File

@ -22,7 +22,6 @@ import (
"math/rand"
"net/http"
"net/http/httptest"
"sort"
"strconv"
"strings"
@ -43,6 +42,7 @@ import (
"k8s.io/apimachinery/pkg/version"
apidiscoveryv2conversion "k8s.io/apiserver/pkg/apis/apidiscovery/v2"
discoveryendpoint "k8s.io/apiserver/pkg/endpoints/discovery/aggregated"
"k8s.io/apiserver/pkg/endpoints/request"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
featuregatetesting "k8s.io/component-base/featuregate/testing"
@ -133,7 +133,7 @@ func fetchPath(handler http.Handler, acceptPrefix string, path string, etag stri
func fetchPathHelper(handler http.Handler, accept string, path string, etag string) (*http.Response, []byte) {
// Expect json-formatted apis group list
w := httptest.NewRecorder()
req := httptest.NewRequest("GET", discoveryPath, nil)
req := httptest.NewRequest(request.MethodGet, discoveryPath, nil)
// Ask for JSON response
req.Header.Set("Accept", accept)

View File

@ -24,6 +24,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"k8s.io/apiserver/pkg/endpoints/request"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
featuregatetesting "k8s.io/component-base/featuregate/testing"
@ -42,7 +43,7 @@ const aggregatedProtoAccept = protobufAccept + aggregatedAcceptSuffix
func fetchPath(handler http.Handler, path, accept string) string {
w := httptest.NewRecorder()
req := httptest.NewRequest("GET", discoveryPath, nil)
req := httptest.NewRequest(request.MethodGet, discoveryPath, nil)
// Ask for JSON response
req.Header.Set("Accept", accept)

View File

@ -204,7 +204,7 @@ func TestAudit(t *testing.T) {
{
"read-only empty",
shortRunningPath,
"GET",
request.MethodGet,
"",
nil,
func(http.ResponseWriter, *http.Request) {},
@ -226,7 +226,7 @@ func TestAudit(t *testing.T) {
{
"short running with auditID",
shortRunningPath,
"GET",
request.MethodGet,
uuid.New().String(),
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -250,7 +250,7 @@ func TestAudit(t *testing.T) {
{
"read-only panic",
shortRunningPath,
"GET",
request.MethodGet,
"",
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -275,7 +275,7 @@ func TestAudit(t *testing.T) {
{
"writing empty",
shortRunningPath,
"PUT",
request.MethodPut,
"",
nil,
func(http.ResponseWriter, *http.Request) {},
@ -297,7 +297,7 @@ func TestAudit(t *testing.T) {
{
"writing sleep",
shortRunningPath,
"PUT",
request.MethodPut,
"",
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -322,7 +322,7 @@ func TestAudit(t *testing.T) {
{
"writing 403+write",
shortRunningPath,
"PUT",
request.MethodPut,
"",
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -347,7 +347,7 @@ func TestAudit(t *testing.T) {
{
"writing panic",
shortRunningPath,
"PUT",
request.MethodPut,
"",
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -371,7 +371,7 @@ func TestAudit(t *testing.T) {
{
"writing write+panic",
shortRunningPath,
"PUT",
request.MethodPut,
"",
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -397,7 +397,7 @@ func TestAudit(t *testing.T) {
{
"empty longrunning",
longRunningPath,
"GET",
request.MethodGet,
"",
nil,
func(http.ResponseWriter, *http.Request) {},
@ -425,7 +425,7 @@ func TestAudit(t *testing.T) {
{
"empty longrunning with audit id",
longRunningPath,
"GET",
request.MethodGet,
uuid.New().String(),
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -455,7 +455,7 @@ func TestAudit(t *testing.T) {
{
"sleep longrunning",
longRunningPath,
"GET",
request.MethodGet,
"",
nil,
func(http.ResponseWriter, *http.Request) {
@ -485,7 +485,7 @@ func TestAudit(t *testing.T) {
{
"sleep+403 longrunning",
longRunningPath,
"GET",
request.MethodGet,
"",
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -516,7 +516,7 @@ func TestAudit(t *testing.T) {
{
"write longrunning",
longRunningPath,
"GET",
request.MethodGet,
"",
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -546,7 +546,7 @@ func TestAudit(t *testing.T) {
{
"403+write longrunning",
longRunningPath,
"GET",
request.MethodGet,
"",
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -577,7 +577,7 @@ func TestAudit(t *testing.T) {
{
"panic longrunning",
longRunningPath,
"GET",
request.MethodGet,
"",
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -601,7 +601,7 @@ func TestAudit(t *testing.T) {
{
"write+panic longrunning",
longRunningPath,
"GET",
request.MethodGet,
"",
nil,
func(w http.ResponseWriter, req *http.Request) {
@ -632,7 +632,7 @@ func TestAudit(t *testing.T) {
{
"omit RequestReceived",
shortRunningPath,
"GET",
request.MethodGet,
"",
[]auditinternal.Stage{auditinternal.StageRequestReceived},
func(w http.ResponseWriter, req *http.Request) {
@ -651,7 +651,7 @@ func TestAudit(t *testing.T) {
{
"emit Panic only",
longRunningPath,
"GET",
request.MethodGet,
"",
[]auditinternal.Stage{auditinternal.StageRequestReceived, auditinternal.StageResponseStarted, auditinternal.StageResponseComplete},
func(w http.ResponseWriter, req *http.Request) {
@ -743,7 +743,7 @@ func TestAudit(t *testing.T) {
func TestAuditNoPanicOnNilUser(t *testing.T) {
fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil)
handler := WithAudit(&fakeHTTPHandler{}, &fakeAuditSink{}, fakeRuleEvaluator, nil)
req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil)
req, _ := http.NewRequest(request.MethodGet, "/api/v1/namespaces/default/pods", nil)
req = withTestContext(req, nil, nil)
req.RemoteAddr = "127.0.0.1"
handler.ServeHTTP(httptest.NewRecorder(), req)
@ -758,7 +758,7 @@ func TestAuditLevelNone(t *testing.T) {
fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelNone, nil)
handler = WithAudit(handler, sink, fakeRuleEvaluator, nil)
req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil)
req, _ := http.NewRequest(request.MethodGet, "/api/v1/namespaces/default/pods", nil)
req.RemoteAddr = "127.0.0.1"
req = withTestContext(req, &user.DefaultInfo{Name: "admin"}, nil)
@ -814,7 +814,7 @@ func TestAuditIDHttpHeader(t *testing.T) {
handler = WithAudit(handler, sink, fakeRuleEvaluator, nil)
handler = WithAuditInit(handler)
req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil)
req, _ := http.NewRequest(request.MethodGet, "/api/v1/namespaces/default/pods", nil)
req.RemoteAddr = "127.0.0.1"
req = withTestContext(req, &user.DefaultInfo{Name: "admin"}, nil)
if test.requestHeader != "" {

View File

@ -26,6 +26,7 @@ import (
auditinternal "k8s.io/apiserver/pkg/apis/audit"
"k8s.io/apiserver/pkg/audit/policy"
"k8s.io/apiserver/pkg/endpoints/request"
)
func TestFailedAuthnAudit(t *testing.T) {
@ -36,7 +37,7 @@ func TestFailedAuthnAudit(t *testing.T) {
http.Error(w, "", http.StatusUnauthorized)
}),
sink, fakeRuleEvaluator)
req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil)
req, _ := http.NewRequest(request.MethodGet, "/api/v1/namespaces/default/pods", nil)
req.RemoteAddr = "127.0.0.1"
req = withTestContext(req, nil, nil)
req.SetBasicAuth("username", "password")
@ -68,7 +69,7 @@ func TestFailedMultipleAuthnAudit(t *testing.T) {
http.Error(w, "", http.StatusUnauthorized)
}),
sink, fakeRuleEvaluator)
req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil)
req, _ := http.NewRequest(request.MethodGet, "/api/v1/namespaces/default/pods", nil)
req.RemoteAddr = "127.0.0.1"
req = withTestContext(req, nil, nil)
req.SetBasicAuth("username", "password")
@ -101,7 +102,7 @@ func TestFailedAuthnAuditWithoutAuthorization(t *testing.T) {
http.Error(w, "", http.StatusUnauthorized)
}),
sink, fakeRuleEvaluator)
req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil)
req, _ := http.NewRequest(request.MethodGet, "/api/v1/namespaces/default/pods", nil)
req.RemoteAddr = "127.0.0.1"
req = withTestContext(req, nil, nil)
handler.ServeHTTP(httptest.NewRecorder(), req)
@ -132,7 +133,7 @@ func TestFailedAuthnAuditOmitted(t *testing.T) {
http.Error(w, "", http.StatusUnauthorized)
}),
sink, fakeRuleEvaluator)
req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil)
req, _ := http.NewRequest(request.MethodGet, "/api/v1/namespaces/default/pods", nil)
req.RemoteAddr = "127.0.0.1"
req = withTestContext(req, nil, nil)
handler.ServeHTTP(httptest.NewRecorder(), req)

View File

@ -19,16 +19,17 @@ package filters
import (
"context"
"errors"
"net/http"
"net/http/httptest"
"reflect"
"testing"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"net/http"
"net/http/httptest"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
batch "k8s.io/api/batch/v1"
@ -52,7 +53,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
EnableAuthorizationSelector bool
}{
"non-resource root": {
Verb: "POST",
Verb: http.MethodPost,
Path: "/",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "post",
@ -60,7 +61,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
},
},
"non-resource api prefix": {
Verb: "GET",
Verb: http.MethodGet,
Path: "/api/",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "get",
@ -68,7 +69,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
},
},
"non-resource group api prefix": {
Verb: "GET",
Verb: http.MethodGet,
Path: "/apis/extensions/",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "get",
@ -77,7 +78,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
},
"resource": {
Verb: "POST",
Verb: http.MethodPost,
Path: "/api/v1/nodes/mynode",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "create",
@ -89,7 +90,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
},
},
"namespaced resource": {
Verb: "PUT",
Verb: http.MethodPut,
Path: "/api/v1/namespaces/myns/pods/mypod",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "update",
@ -102,7 +103,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
},
},
"API group resource": {
Verb: "GET",
Verb: http.MethodGet,
Path: "/apis/batch/v1/namespaces/myns/jobs",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "list",
@ -115,7 +116,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
},
},
"disabled, ignore good field selector": {
Verb: "GET",
Verb: http.MethodGet,
Path: "/apis/batch/v1/namespaces/myns/jobs?fieldSelector%=foo%3Dbar",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "list",
@ -128,7 +129,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
},
},
"enabled, good field selector": {
Verb: "GET",
Verb: http.MethodGet,
Path: "/apis/batch/v1/namespaces/myns/jobs?fieldSelector=foo%3D%3Dbar",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "list",
@ -145,7 +146,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
EnableAuthorizationSelector: true,
},
"enabled, bad field selector": {
Verb: "GET",
Verb: http.MethodGet,
Path: "/apis/batch/v1/namespaces/myns/jobs?fieldSelector=%2Abar",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "list",
@ -160,7 +161,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
EnableAuthorizationSelector: true,
},
"disabled, ignore good label selector": {
Verb: "GET",
Verb: http.MethodGet,
Path: "/apis/batch/v1/namespaces/myns/jobs?labelSelector%=foo%3Dbar",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "list",
@ -173,7 +174,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
},
},
"enabled, good label selector": {
Verb: "GET",
Verb: http.MethodGet,
Path: "/apis/batch/v1/namespaces/myns/jobs?labelSelector=foo%3D%3Dbar",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "list",
@ -190,7 +191,7 @@ func TestGetAuthorizerAttributes(t *testing.T) {
EnableAuthorizationSelector: true,
},
"enabled, bad label selector": {
Verb: "GET",
Verb: http.MethodGet,
Path: "/apis/batch/v1/namespaces/myns/jobs?labelSelector=%2Abar",
ExpectedAttributes: &authorizer.AttributesRecord{
Verb: "list",
@ -284,7 +285,7 @@ func TestAuditAnnotation(t *testing.T) {
handler := WithAuthorization(&fakeHTTPHandler{}, tc.authorizer, negotiatedSerializer)
// TODO: fake audit injector
req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil)
req, _ := http.NewRequest(http.MethodGet, "/api/v1/namespaces/default/pods", nil)
req = withTestContext(req, nil, &auditinternal.Event{Level: auditinternal.LevelMetadata})
ae := audit.AuditEventFrom(req.Context())
req.RemoteAddr = "127.0.0.1"

View File

@ -532,7 +532,7 @@ func TestImpersonationFilter(t *testing.T) {
ctx = request.WithUser(request.NewContext(), tc.user)
}()
req, err := http.NewRequest("GET", server.URL, nil)
req, err := http.NewRequest(http.MethodGet, server.URL, nil)
if err != nil {
t.Errorf("%s: unexpected error: %v", tc.name, err)
return

View File

@ -258,7 +258,7 @@ func TestRecordAuthorizationMetricsMetrics(t *testing.T) {
handler := WithAuthorization(&fakeHTTPHandler{}, tt.authorizer, negotiatedSerializer)
// TODO: fake audit injector
req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil)
req, _ := http.NewRequest(http.MethodGet, "/api/v1/namespaces/default/pods", nil)
req = withTestContext(req, nil, audit)
req.RemoteAddr = "127.0.0.1"
handler.ServeHTTP(httptest.NewRecorder(), req)

View File

@ -1233,7 +1233,7 @@ func TestPerRequestWithSlowReader(t *testing.T) {
defer close(clientErrCh)
// we don't set up a request context with deadline on the client-side
req, err := http.NewRequestWithContext(context.Background(), "GET", server.URL+"/foo", nil)
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, server.URL+"/foo", nil)
if err != nil {
t.Errorf("failed to create a new request: %v", err)
return
@ -1313,7 +1313,7 @@ func TestPerRequestWithSlowReader(t *testing.T) {
func sendWithTrace(t *testing.T, client *http.Client, url string, f func(*testing.T, httptrace.GotConnInfo)) (*http.Response, error) {
t.Helper()
req, err := http.NewRequest("GET", url, nil)
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
t.Fatalf("failed to create new request: %v", err)
}

View File

@ -237,7 +237,7 @@ func TestDeleteCollectionWithNoContextDeadlineEnforced(t *testing.T) {
}
handler := DeleteCollection(fakeCollectionDeleterFunc(fakeDeleterFn), false, scope, nil)
request, err := http.NewRequest("GET", "/test", nil)
request, err := http.NewRequest(request.MethodGet, "/test", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

View File

@ -80,9 +80,9 @@ func TestLazyVerb(t *testing.T) {
assert.Equal(t, "unknown", fmt.Sprintf("%v", &lazyVerb{}))
u, _ := url.Parse("?watch=true")
req := &http.Request{Method: "GET", URL: u}
req := &http.Request{Method: request.MethodGet, URL: u}
verbWithReq := &lazyVerb{req: req}
assert.Equal(t, "WATCH", fmt.Sprintf("%v", verbWithReq))
assert.Equal(t, request.MethodWatch, fmt.Sprintf("%v", verbWithReq))
}
func TestLazyApiGroup(t *testing.T) {

View File

@ -64,9 +64,9 @@ func TestForbidden(t *testing.T) {
contentType string
}{
{`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User \"NAME\" cannot GET path \"/whatever\"","reason":"Forbidden","details":{},"code":403}
`, authorizer.AttributesRecord{User: u, Verb: "GET", Path: "/whatever"}, "", "application/json"},
`, authorizer.AttributesRecord{User: u, Verb: request.MethodGet, Path: "/whatever"}, "", "application/json"},
{`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"forbidden: User \"NAME\" cannot GET path \"/\u0026lt;script\u0026gt;\"","reason":"Forbidden","details":{},"code":403}
`, authorizer.AttributesRecord{User: u, Verb: "GET", Path: "/<script>"}, "", "application/json"},
`, authorizer.AttributesRecord{User: u, Verb: request.MethodGet, Path: "/<script>"}, "", "application/json"},
{`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"pod is forbidden: User \"NAME\" cannot get resource \"pod\" in API group \"\" at the cluster scope","reason":"Forbidden","details":{"kind":"pod"},"code":403}
`, authorizer.AttributesRecord{User: u, Verb: "get", Resource: "pod", ResourceRequest: true}, "", "application/json"},
{`{"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"pod \"mypod\" is forbidden: User \"NAME\" cannot get resource \"pod\" in API group \"\" at the cluster scope","reason":"Forbidden","details":{"name":"mypod","kind":"pod"},"code":403}

View File

@ -181,7 +181,7 @@ func TestLimitedReadBody(t *testing.T) {
defer metrics.RequestBodySizes.Reset()
defer legacyregistry.Reset()
req, err := http.NewRequest("POST", "/", tc.requestBody)
req, err := http.NewRequest(request.MethodPost, "/", tc.requestBody)
if err != nil {
t.Errorf("err not expected: got %v", err)
}

View File

@ -42,6 +42,7 @@ import (
"k8s.io/apiserver/pkg/endpoints/handlers"
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
"k8s.io/apiserver/pkg/endpoints/metrics"
"k8s.io/apiserver/pkg/endpoints/request"
utilwarning "k8s.io/apiserver/pkg/endpoints/warning"
"k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/registry/rest"
@ -62,9 +63,9 @@ type APIInstaller struct {
minRequestTimeout time.Duration
}
// Struct capturing information about an action ("GET", "POST", "WATCH", "PROXY", etc).
// Struct capturing information about an action (MethodGet, MethodPost, MethodWatch, MethodProxy, etc).
type action struct {
Verb string // Verb identifying the action ("GET", "POST", "WATCH", "PROXY", etc).
Verb string // Verb identifying the action (MethodGet, MethodPost, MethodWatch, MethodProxy, etc).
Path string // The path of the action
Params []*restful.Parameter // List of parameters associated with the action.
Namer handlers.ScopeNamer
@ -175,17 +176,17 @@ type documentable interface {
// toDiscoveryKubeVerb maps an action.Verb to the logical kube verb, used for discovery
var toDiscoveryKubeVerb = map[string]string{
"CONNECT": "", // do not list in discovery.
"DELETE": "delete",
"DELETECOLLECTION": "deletecollection",
"GET": "get",
"LIST": "list",
"PATCH": "patch",
"POST": "create",
"PROXY": "proxy",
"PUT": "update",
"WATCH": "watch",
"WATCHLIST": "watch",
request.MethodConnect: "", // do not list in discovery.
request.MethodDelete: "delete",
request.MethodDeleteCollection: "deletecollection",
request.MethodGet: "get",
request.MethodList: "list",
request.MethodPatch: "patch",
request.MethodPost: "create",
request.MethodProxy: "proxy",
request.MethodPut: "update",
request.MethodWatch: "watch",
request.MethodWatchList: "watch",
}
// Install handlers for API resources.
@ -520,24 +521,24 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
// Handler for standard REST verbs (GET, PUT, POST and DELETE).
// Add actions at the resource path: /api/apiVersion/resource
actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer, false}, isLister)
actions = appendIf(actions, action{"POST", resourcePath, resourceParams, namer, false}, isCreater)
actions = appendIf(actions, action{"DELETECOLLECTION", resourcePath, resourceParams, namer, false}, isCollectionDeleter)
actions = appendIf(actions, action{request.MethodList, resourcePath, resourceParams, namer, false}, isLister)
actions = appendIf(actions, action{request.MethodPost, resourcePath, resourceParams, namer, false}, isCreater)
actions = appendIf(actions, action{request.MethodDeleteCollection, resourcePath, resourceParams, namer, false}, isCollectionDeleter)
// DEPRECATED in 1.11
actions = appendIf(actions, action{"WATCHLIST", "watch/" + resourcePath, resourceParams, namer, false}, allowWatchList)
actions = appendIf(actions, action{request.MethodWatchList, "watch/" + resourcePath, resourceParams, namer, false}, allowWatchList)
// Add actions at the item path: /api/apiVersion/resource/{name}
actions = appendIf(actions, action{"GET", itemPath, nameParams, namer, false}, isGetter)
actions = appendIf(actions, action{request.MethodGet, itemPath, nameParams, namer, false}, isGetter)
if getSubpath {
actions = appendIf(actions, action{"GET", itemPath + "/{path:*}", proxyParams, namer, false}, isGetter)
actions = appendIf(actions, action{request.MethodGet, itemPath + "/{path:*}", proxyParams, namer, false}, isGetter)
}
actions = appendIf(actions, action{"PUT", itemPath, nameParams, namer, false}, isUpdater)
actions = appendIf(actions, action{"PATCH", itemPath, nameParams, namer, false}, isPatcher)
actions = appendIf(actions, action{"DELETE", itemPath, nameParams, namer, false}, isGracefulDeleter)
actions = appendIf(actions, action{request.MethodPut, itemPath, nameParams, namer, false}, isUpdater)
actions = appendIf(actions, action{request.MethodPatch, itemPath, nameParams, namer, false}, isPatcher)
actions = appendIf(actions, action{request.MethodDelete, itemPath, nameParams, namer, false}, isGracefulDeleter)
// DEPRECATED in 1.11
actions = appendIf(actions, action{"WATCH", "watch/" + itemPath, nameParams, namer, false}, isWatcher)
actions = appendIf(actions, action{"CONNECT", itemPath, nameParams, namer, false}, isConnecter)
actions = appendIf(actions, action{"CONNECT", itemPath + "/{path:*}", proxyParams, namer, false}, isConnecter && connectSubpath)
actions = appendIf(actions, action{request.MethodWatch, "watch/" + itemPath, nameParams, namer, false}, isWatcher)
actions = appendIf(actions, action{request.MethodConnect, itemPath, nameParams, namer, false}, isConnecter)
actions = appendIf(actions, action{request.MethodConnect, itemPath + "/{path:*}", proxyParams, namer, false}, isConnecter && connectSubpath)
default:
namespaceParamName := "namespaces"
// Handler for standard REST verbs (GET, PUT, POST and DELETE).
@ -565,31 +566,31 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
ClusterScoped: false,
}
actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer, false}, isLister)
actions = appendIf(actions, action{"POST", resourcePath, resourceParams, namer, false}, isCreater)
actions = appendIf(actions, action{"DELETECOLLECTION", resourcePath, resourceParams, namer, false}, isCollectionDeleter)
actions = appendIf(actions, action{request.MethodList, resourcePath, resourceParams, namer, false}, isLister)
actions = appendIf(actions, action{request.MethodPost, resourcePath, resourceParams, namer, false}, isCreater)
actions = appendIf(actions, action{request.MethodDeleteCollection, resourcePath, resourceParams, namer, false}, isCollectionDeleter)
// DEPRECATED in 1.11
actions = appendIf(actions, action{"WATCHLIST", "watch/" + resourcePath, resourceParams, namer, false}, allowWatchList)
actions = appendIf(actions, action{request.MethodWatchList, "watch/" + resourcePath, resourceParams, namer, false}, allowWatchList)
actions = appendIf(actions, action{"GET", itemPath, nameParams, namer, false}, isGetter)
actions = appendIf(actions, action{request.MethodGet, itemPath, nameParams, namer, false}, isGetter)
if getSubpath {
actions = appendIf(actions, action{"GET", itemPath + "/{path:*}", proxyParams, namer, false}, isGetter)
actions = appendIf(actions, action{request.MethodGet, itemPath + "/{path:*}", proxyParams, namer, false}, isGetter)
}
actions = appendIf(actions, action{"PUT", itemPath, nameParams, namer, false}, isUpdater)
actions = appendIf(actions, action{"PATCH", itemPath, nameParams, namer, false}, isPatcher)
actions = appendIf(actions, action{"DELETE", itemPath, nameParams, namer, false}, isGracefulDeleter)
actions = appendIf(actions, action{request.MethodPut, itemPath, nameParams, namer, false}, isUpdater)
actions = appendIf(actions, action{request.MethodPatch, itemPath, nameParams, namer, false}, isPatcher)
actions = appendIf(actions, action{request.MethodDelete, itemPath, nameParams, namer, false}, isGracefulDeleter)
// DEPRECATED in 1.11
actions = appendIf(actions, action{"WATCH", "watch/" + itemPath, nameParams, namer, false}, isWatcher)
actions = appendIf(actions, action{"CONNECT", itemPath, nameParams, namer, false}, isConnecter)
actions = appendIf(actions, action{"CONNECT", itemPath + "/{path:*}", proxyParams, namer, false}, isConnecter && connectSubpath)
actions = appendIf(actions, action{request.MethodWatch, "watch/" + itemPath, nameParams, namer, false}, isWatcher)
actions = appendIf(actions, action{request.MethodConnect, itemPath, nameParams, namer, false}, isConnecter)
actions = appendIf(actions, action{request.MethodConnect, itemPath + "/{path:*}", proxyParams, namer, false}, isConnecter && connectSubpath)
// list or post across namespace.
// For ex: LIST all pods in all namespaces by sending a LIST request at /api/apiVersion/pods.
// TODO: more strongly type whether a resource allows these actions on "all namespaces" (bulk delete)
if !isSubresource {
actions = appendIf(actions, action{"LIST", resource, params, namer, true}, isLister)
actions = appendIf(actions, action{request.MethodList, resource, params, namer, true}, isLister)
// DEPRECATED in 1.11
actions = appendIf(actions, action{"WATCHLIST", "watch/" + resource, params, namer, true}, allowWatchList)
actions = appendIf(actions, action{request.MethodWatchList, "watch/" + resource, params, namer, true}, allowWatchList)
}
}
@ -740,7 +741,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
requestScope = "resource"
operationSuffix = operationSuffix + "WithPath"
}
if strings.Contains(action.Path, "/{name}") || action.Verb == "POST" {
if strings.Contains(action.Path, "/{name}") || action.Verb == request.MethodPost {
requestScope = "resource"
}
if action.AllNamespaces {
@ -794,7 +795,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
switch action.Verb {
case "GET": // Get a resource.
case request.MethodGet: // Get a resource.
var handler restful.RouteFunction
if isGetterWithOptions {
handler = restfulGetResourceWithOptions(getterWithOptions, reqScope, isSubresource)
@ -828,7 +829,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
addParams(route, action.Params)
routes = append(routes, route)
case "LIST": // List all resources of a kind.
case request.MethodList: // List all resources of a kind.
doc := "list objects of kind " + kind
if isSubresource {
doc = "list " + subresource + " of objects of kind " + kind
@ -861,7 +862,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
addParams(route, action.Params)
routes = append(routes, route)
case "PUT": // Update a resource.
case request.MethodPut: // Update a resource.
doc := "replace the specified " + kind
if isSubresource {
doc = "replace " + subresource + " of the specified " + kind
@ -884,7 +885,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
addParams(route, action.Params)
routes = append(routes, route)
case "PATCH": // Partially update a resource
case request.MethodPatch: // Partially update a resource
doc := "partially update the specified " + kind
if isSubresource {
doc = "partially update " + subresource + " of the specified " + kind
@ -916,7 +917,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
addParams(route, action.Params)
routes = append(routes, route)
case "POST": // Create a resource.
case request.MethodPost: // Create a resource.
var handler restful.RouteFunction
if isNamedCreater {
handler = restfulCreateNamedResource(namedCreater, reqScope, admit)
@ -947,7 +948,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
addParams(route, action.Params)
routes = append(routes, route)
case "DELETE": // Delete a resource.
case request.MethodDelete: // Delete a resource.
article := GetArticleForNoun(kind, " ")
doc := "delete" + article + kind
if isSubresource {
@ -976,7 +977,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
addParams(route, action.Params)
routes = append(routes, route)
case "DELETECOLLECTION":
case request.MethodDeleteCollection:
doc := "delete collection of " + kind
if isSubresource {
doc = "delete collection of " + subresource + " of a " + kind
@ -1003,7 +1004,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
addParams(route, action.Params)
routes = append(routes, route)
// deprecated in 1.11
case "WATCH": // Watch a resource.
case request.MethodWatch: // Watch a resource.
doc := "watch changes to an object of kind " + kind
if isSubresource {
doc = "watch changes to " + subresource + " of an object of kind " + kind
@ -1024,7 +1025,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
addParams(route, action.Params)
routes = append(routes, route)
// deprecated in 1.11
case "WATCHLIST": // Watch all resources of a kind.
case request.MethodWatchList: // Watch all resources of a kind.
doc := "watch individual changes to a list of " + kind
if isSubresource {
doc = "watch individual changes to a list of " + subresource + " of " + kind
@ -1044,7 +1045,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
addParams(route, action.Params)
routes = append(routes, route)
case "CONNECT":
case request.MethodConnect:
for _, method := range connecter.ConnectMethods() {
connectProducedObject := storageMeta.ProducesObject(method)
if connectProducedObject == nil {

View File

@ -322,20 +322,20 @@ var (
// these are the valid request methods which we report in our metrics. Any other request methods
// will be aggregated under 'unknown'
validRequestMethods = utilsets.NewString(
"APPLY",
"CONNECT",
"CREATE",
"DELETE",
"DELETECOLLECTION",
"GET",
"LIST",
"PATCH",
"POST",
"PROXY",
"PUT",
"UPDATE",
"WATCH",
"WATCHLIST")
MethodApply,
MethodConnect,
MethodCreate,
MethodDelete,
MethodDeleteCollection,
MethodGet,
MethodList,
MethodPatch,
MethodPost,
MethodProxy,
MethodPut,
MethodUpdate,
MethodWatch,
MethodWatchList)
// These are the valid connect requests which we report in our metrics.
validConnectRequests = utilsets.NewString(
@ -346,6 +346,24 @@ var (
"proxy")
)
const (
MethodApply string = request.MethodApply
MethodConnect string = request.MethodConnect
MethodCreate string = request.MethodCreate
MethodDelete string = request.MethodDelete
MethodDeleteCollection string = request.MethodDeleteCollection
MethodGet string = request.MethodGet
MethodHead string = request.MethodHead // TODO: why not in validRequestMethods?
MethodList string = request.MethodList
MethodPatch string = request.MethodPatch
MethodPost string = request.MethodPost
MethodProxy string = request.MethodProxy
MethodPut string = request.MethodPut
MethodUpdate string = request.MethodUpdate
MethodWatch string = request.MethodWatch
MethodWatchList string = request.MethodWatchList
)
const (
// ReadOnlyKind is a string identifying read only request kind
ReadOnlyKind = "readOnly"
@ -605,7 +623,7 @@ func MonitorRequest(req *http.Request, verb, group, version, resource, subresour
requestSliLatencies.WithContext(req.Context()).WithLabelValues(reportedVerb, group, version, resource, subresource, scope, component).Observe(sliLatency)
}
// We are only interested in response sizes of read requests.
if verb == "GET" || verb == "LIST" {
if verb == MethodGet || verb == MethodList {
responseSizes.WithContext(req.Context()).WithLabelValues(reportedVerb, group, version, resource, subresource, scope, component).Observe(float64(respSize))
}
}
@ -701,11 +719,11 @@ func CleanListScope(ctx context.Context, opts *metainternalversion.ListOptions)
// UPPERCASE.
func CanonicalVerb(verb string, scope string) string {
switch verb {
case "GET", "HEAD":
case MethodGet, MethodHead:
if scope != "resource" && scope != "" {
return "LIST"
return request.MethodList
}
return "GET"
return MethodGet
default:
return verb
}
@ -715,18 +733,18 @@ func CanonicalVerb(verb string, scope string) string {
// LIST, APPLY from PATCH and CONNECT from others.
func CleanVerb(verb string, request *http.Request, requestInfo *request.RequestInfo) string {
reportedVerb := verb
if suggestedVerb := getVerbIfWatch(request); suggestedVerb == "WATCH" {
reportedVerb = "WATCH"
if suggestedVerb := getVerbIfWatch(request); suggestedVerb == MethodWatch {
reportedVerb = MethodWatch
}
// normalize the legacy WATCHLIST to WATCH to ensure users aren't surprised by metrics
if verb == "WATCHLIST" {
reportedVerb = "WATCH"
if verb == MethodWatchList {
reportedVerb = MethodWatch
}
if verb == "PATCH" && request.Header.Get("Content-Type") == string(types.ApplyPatchType) {
reportedVerb = "APPLY"
if verb == MethodPatch && request.Header.Get("Content-Type") == string(types.ApplyPatchType) {
reportedVerb = MethodApply
}
if requestInfo != nil && requestInfo.IsResourceRequest && len(requestInfo.Subresource) > 0 && validConnectRequests.Has(requestInfo.Subresource) {
reportedVerb = "CONNECT"
reportedVerb = MethodConnect
}
return reportedVerb
}
@ -761,8 +779,8 @@ func cleanVerb(verb, suggestedVerb string, request *http.Request, requestInfo *r
// deprecated path pattern for watch of:
// GET /api/{version}/watch/{resource}
// We correct it manually based on the pass verb from the installer.
if suggestedVerb == "WATCH" || suggestedVerb == "WATCHLIST" {
return "WATCH"
if suggestedVerb == MethodWatch || suggestedVerb == MethodWatchList {
return MethodWatch
}
reportedVerb := CleanVerb(verb, request, requestInfo)
if validRequestMethods.Has(reportedVerb) {
@ -773,11 +791,11 @@ func cleanVerb(verb, suggestedVerb string, request *http.Request, requestInfo *r
// getVerbIfWatch additionally ensures that GET or List would be transformed to WATCH
func getVerbIfWatch(req *http.Request) string {
if strings.ToUpper(req.Method) == "GET" || strings.ToUpper(req.Method) == "LIST" {
if strings.ToUpper(req.Method) == MethodGet || strings.ToUpper(req.Method) == request.MethodList {
// see apimachinery/pkg/runtime/conversion.go Convert_Slice_string_To_bool
if values := req.URL.Query()["watch"]; len(values) > 0 {
if value := strings.ToLower(values[0]); value != "0" && value != "false" {
return "WATCH"
return request.MethodWatch
}
}
}

View File

@ -48,97 +48,97 @@ func TestCleanVerb(t *testing.T) {
},
{
desc: "LIST should normally map to LIST",
initialVerb: "LIST",
initialVerb: request.MethodList,
request: nil,
expectedVerb: "LIST",
expectedVerb: request.MethodList,
},
{
desc: "LIST should be transformed to WATCH if we have the right query param on the request",
initialVerb: "LIST",
initialVerb: request.MethodList,
request: &http.Request{
Method: "GET",
Method: request.MethodGet,
URL: &url.URL{
RawQuery: "watch=true",
},
},
expectedVerb: "WATCH",
expectedVerb: request.MethodWatch,
},
{
desc: "LIST isn't transformed to WATCH if we have query params that do not include watch",
initialVerb: "LIST",
initialVerb: request.MethodList,
request: &http.Request{
Method: "GET",
Method: request.MethodGet,
URL: &url.URL{
RawQuery: "blah=asdf&something=else",
},
},
expectedVerb: "LIST",
expectedVerb: request.MethodList,
},
{
// The above may seem counter-intuitive, but it actually is needed for cases like
// watching a single item, e.g.:
// /api/v1/namespaces/foo/pods/bar?fieldSelector=metadata.name=baz&watch=true
desc: "GET is transformed to WATCH if we have the right query param on the request",
initialVerb: "GET",
initialVerb: request.MethodGet,
request: &http.Request{
Method: "GET",
Method: request.MethodGet,
URL: &url.URL{
RawQuery: "watch=true",
},
},
expectedVerb: "WATCH",
expectedVerb: request.MethodWatch,
},
{
desc: "LIST is transformed to WATCH for the old pattern watch",
initialVerb: "LIST",
suggestedVerb: "WATCH",
initialVerb: request.MethodList,
suggestedVerb: request.MethodWatch,
request: &http.Request{
Method: "GET",
Method: request.MethodGet,
URL: &url.URL{
RawQuery: "/api/v1/watch/pods",
},
},
expectedVerb: "WATCH",
expectedVerb: request.MethodWatch,
},
{
desc: "LIST is transformed to WATCH for the old pattern watchlist",
initialVerb: "LIST",
suggestedVerb: "WATCHLIST",
initialVerb: request.MethodList,
suggestedVerb: request.MethodWatchList,
request: &http.Request{
Method: "GET",
Method: request.MethodGet,
URL: &url.URL{
RawQuery: "/api/v1/watch/pods",
},
},
expectedVerb: "WATCH",
expectedVerb: request.MethodWatch,
},
{
desc: "WATCHLIST should be transformed to WATCH",
initialVerb: "WATCHLIST",
initialVerb: request.MethodWatchList,
request: nil,
expectedVerb: "WATCH",
expectedVerb: request.MethodWatch,
},
{
desc: "PATCH should be transformed to APPLY with the right content type",
initialVerb: "PATCH",
initialVerb: request.MethodPatch,
request: &http.Request{
Header: http.Header{
"Content-Type": []string{"application/apply-patch+yaml"},
},
},
expectedVerb: "APPLY",
expectedVerb: request.MethodApply,
},
{
desc: "PATCH shouldn't be transformed to APPLY without the right content type",
initialVerb: "PATCH",
initialVerb: request.MethodPatch,
request: nil,
expectedVerb: "PATCH",
expectedVerb: request.MethodPatch,
},
{
desc: "WATCHLIST should be transformed to WATCH",
initialVerb: "WATCHLIST",
initialVerb: request.MethodWatchList,
request: nil,
expectedVerb: "WATCH",
expectedVerb: request.MethodWatch,
},
{
desc: "unexpected verbs should be designated as unknown",
@ -148,26 +148,26 @@ func TestCleanVerb(t *testing.T) {
},
{
desc: "Pod logs should be transformed to CONNECT",
initialVerb: "GET",
initialVerb: request.MethodGet,
request: &http.Request{
Method: "GET",
Method: request.MethodGet,
URL: &url.URL{
RawQuery: "/api/v1/namespaces/default/pods/test-pod/log",
},
},
requestInfo: &request.RequestInfo{
Verb: "GET",
Verb: request.MethodGet,
Resource: "pods",
IsResourceRequest: true,
Subresource: "log",
},
expectedVerb: "CONNECT",
expectedVerb: request.MethodConnect,
},
{
desc: "Pod exec should be transformed to CONNECT",
initialVerb: "POST",
initialVerb: request.MethodPost,
request: &http.Request{
Method: "POST",
Method: request.MethodPost,
URL: &url.URL{
RawQuery: "/api/v1/namespaces/default/pods/test-pod/exec?command=sh",
},
@ -180,18 +180,18 @@ func TestCleanVerb(t *testing.T) {
},
},
requestInfo: &request.RequestInfo{
Verb: "POST",
Verb: request.MethodPost,
Resource: "pods",
IsResourceRequest: true,
Subresource: "exec",
},
expectedVerb: "CONNECT",
expectedVerb: request.MethodConnect,
},
{
desc: "Pod portforward should be transformed to CONNECT",
initialVerb: "POST",
initialVerb: request.MethodPost,
request: &http.Request{
Method: "POST",
Method: request.MethodPost,
URL: &url.URL{
RawQuery: "/api/v1/namespaces/default/pods/test-pod/portforward",
},
@ -204,30 +204,30 @@ func TestCleanVerb(t *testing.T) {
},
},
requestInfo: &request.RequestInfo{
Verb: "POST",
Verb: request.MethodPost,
Resource: "pods",
IsResourceRequest: true,
Subresource: "portforward",
},
expectedVerb: "CONNECT",
expectedVerb: request.MethodConnect,
},
{
desc: "Deployment scale should not be transformed to CONNECT",
initialVerb: "PUT",
initialVerb: request.MethodPut,
request: &http.Request{
Method: "PUT",
Method: request.MethodPut,
URL: &url.URL{
RawQuery: "/apis/apps/v1/namespaces/default/deployments/test-1/scale",
},
Header: map[string][]string{},
},
requestInfo: &request.RequestInfo{
Verb: "PUT",
Verb: request.MethodPut,
Resource: "deployments",
IsResourceRequest: true,
Subresource: "scale",
},
expectedVerb: "PUT",
expectedVerb: request.MethodPut,
},
}
for _, tt := range testCases {
@ -382,7 +382,7 @@ func TestRecordDroppedRequests(t *testing.T) {
{
desc: "list pods",
request: &http.Request{
Method: "GET",
Method: request.MethodGet,
URL: &url.URL{
RawPath: "/api/v1/pods",
},
@ -404,7 +404,7 @@ func TestRecordDroppedRequests(t *testing.T) {
{
desc: "post pods",
request: &http.Request{
Method: "POST",
Method: request.MethodPost,
URL: &url.URL{
RawPath: "/api/v1/namespaces/foo/pods",
},
@ -426,7 +426,7 @@ func TestRecordDroppedRequests(t *testing.T) {
{
desc: "dry-run patch job status",
request: &http.Request{
Method: "PATCH",
Method: request.MethodPatch,
URL: &url.URL{
RawPath: "/apis/batch/v1/namespaces/foo/jobs/bar/status",
RawQuery: "dryRun=All",

View File

@ -24,6 +24,7 @@ import (
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/endpoints/request"
genericapitesting "k8s.io/apiserver/pkg/endpoints/testing"
"k8s.io/apiserver/pkg/registry/rest"
)
@ -46,7 +47,7 @@ func TestPatch(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("PATCH", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`)))
request, err := http.NewRequest(request.MethodPatch, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`)))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -81,22 +82,22 @@ func TestForbiddenForceOnNonApply(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("PATCH", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`)))
req, err := http.NewRequest(request.MethodPatch, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`)))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request.Header.Set("Content-Type", "application/merge-patch+json; charset=UTF-8")
_, err = client.Do(request)
req.Header.Set("Content-Type", "application/merge-patch+json; charset=UTF-8")
_, err = client.Do(req)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err = http.NewRequest("PATCH", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID+"?force=true", bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`)))
req, err = http.NewRequest(request.MethodPatch, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID+"?force=true", bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`)))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request.Header.Set("Content-Type", "application/merge-patch+json; charset=UTF-8")
response, err := client.Do(request)
req.Header.Set("Content-Type", "application/merge-patch+json; charset=UTF-8")
response, err := client.Do(req)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -104,12 +105,12 @@ func TestForbiddenForceOnNonApply(t *testing.T) {
t.Errorf("Unexpected response %#v", response)
}
request, err = http.NewRequest("PATCH", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID+"?force=false", bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`)))
req, err = http.NewRequest(request.MethodPatch, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID+"?force=false", bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`)))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request.Header.Set("Content-Type", "application/merge-patch+json; charset=UTF-8")
response, err = client.Do(request)
req.Header.Set("Content-Type", "application/merge-patch+json; charset=UTF-8")
response, err = client.Do(req)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -136,7 +137,7 @@ func TestPatchRequiresMatchingName(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("PATCH", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"metadata":{"name":"idbar"}}`)))
request, err := http.NewRequest(request.MethodPatch, server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"metadata":{"name":"idbar"}}`)))
if err != nil {
t.Errorf("unexpected error: %v", err)
}

View File

@ -0,0 +1,37 @@
/*
Copyright 2025 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package request
import "net/http"
const (
MethodApply string = "APPLY"
MethodConnect string = http.MethodConnect
MethodCreate string = "CREATE"
MethodDelete string = http.MethodDelete
MethodDeleteCollection string = "DELETECOLLECTION"
MethodGet string = http.MethodGet
MethodHead string = http.MethodHead
MethodList string = "LIST"
MethodPatch string = http.MethodPatch
MethodPost string = http.MethodPost
MethodProxy string = "PROXY"
MethodPut string = http.MethodPut
MethodUpdate string = "UPDATE"
MethodWatch string = "WATCH"
MethodWatchList string = "WATCHLIST"
)

View File

@ -175,15 +175,15 @@ func (r *RequestInfoFactory) NewRequestInfo(req *http.Request) (*RequestInfo, er
} else {
switch req.Method {
case "POST":
case MethodPost:
requestInfo.Verb = "create"
case "GET", "HEAD":
case MethodGet, MethodHead:
requestInfo.Verb = "get"
case "PUT":
case MethodPut:
requestInfo.Verb = "update"
case "PATCH":
case MethodPatch:
requestInfo.Verb = "patch"
case "DELETE":
case MethodDelete:
requestInfo.Verb = "delete"
default:
requestInfo.Verb = ""

View File

@ -47,49 +47,49 @@ func TestGetAPIRequestInfo(t *testing.T) {
}{
// resource paths
{"GET", "/api/v1/namespaces", "list", "api", "", "v1", "", "namespaces", "", "", []string{"namespaces"}},
{"GET", "/api/v1/namespaces/other", "get", "api", "", "v1", "other", "namespaces", "", "other", []string{"namespaces", "other"}},
{MethodGet, "/api/v1/namespaces", "list", "api", "", "v1", "", "namespaces", "", "", []string{"namespaces"}},
{MethodGet, "/api/v1/namespaces/other", "get", "api", "", "v1", "other", "namespaces", "", "other", []string{"namespaces", "other"}},
{"GET", "/api/v1/namespaces/other/pods", "list", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/namespaces/other/pods/foo", "get", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"HEAD", "/api/v1/namespaces/other/pods/foo", "get", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"GET", "/api/v1/pods", "list", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{"HEAD", "/api/v1/pods", "list", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/namespaces/other/pods/foo", "get", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"GET", "/api/v1/namespaces/other/pods", "list", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{MethodGet, "/api/v1/namespaces/other/pods", "list", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{MethodGet, "/api/v1/namespaces/other/pods/foo", "get", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{MethodHead, "/api/v1/namespaces/other/pods/foo", "get", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{MethodGet, "/api/v1/pods", "list", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{MethodHead, "/api/v1/pods", "list", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{MethodGet, "/api/v1/namespaces/other/pods/foo", "get", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{MethodGet, "/api/v1/namespaces/other/pods", "list", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
// special verbs
{"GET", "/api/v1/proxy/namespaces/other/pods/foo", "proxy", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"GET", "/api/v1/proxy/namespaces/other/pods/foo/subpath/not/a/subresource", "proxy", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo", "subpath", "not", "a", "subresource"}},
{"GET", "/api/v1/watch/pods", "watch", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/pods?watch=true", "watch", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/pods?watch=false", "list", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/watch/namespaces/other/pods", "watch", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/namespaces/other/pods?watch=1", "watch", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{"GET", "/api/v1/namespaces/other/pods?watch=0", "list", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{MethodGet, "/api/v1/proxy/namespaces/other/pods/foo", "proxy", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{MethodGet, "/api/v1/proxy/namespaces/other/pods/foo/subpath/not/a/subresource", "proxy", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo", "subpath", "not", "a", "subresource"}},
{MethodGet, "/api/v1/watch/pods", "watch", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{MethodGet, "/api/v1/pods?watch=true", "watch", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{MethodGet, "/api/v1/pods?watch=false", "list", "api", "", "v1", namespaceAll, "pods", "", "", []string{"pods"}},
{MethodGet, "/api/v1/watch/namespaces/other/pods", "watch", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{MethodGet, "/api/v1/namespaces/other/pods?watch=1", "watch", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{MethodGet, "/api/v1/namespaces/other/pods?watch=0", "list", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
// subresource identification
{"GET", "/api/v1/namespaces/other/pods/foo/status", "get", "api", "", "v1", "other", "pods", "status", "foo", []string{"pods", "foo", "status"}},
{"GET", "/api/v1/namespaces/other/pods/foo/proxy/subpath", "get", "api", "", "v1", "other", "pods", "proxy", "foo", []string{"pods", "foo", "proxy", "subpath"}},
{"PUT", "/api/v1/namespaces/other/finalize", "update", "api", "", "v1", "other", "namespaces", "finalize", "other", []string{"namespaces", "other", "finalize"}},
{"PUT", "/api/v1/namespaces/other/status", "update", "api", "", "v1", "other", "namespaces", "status", "other", []string{"namespaces", "other", "status"}},
{MethodGet, "/api/v1/namespaces/other/pods/foo/status", "get", "api", "", "v1", "other", "pods", "status", "foo", []string{"pods", "foo", "status"}},
{MethodGet, "/api/v1/namespaces/other/pods/foo/proxy/subpath", "get", "api", "", "v1", "other", "pods", "proxy", "foo", []string{"pods", "foo", "proxy", "subpath"}},
{MethodPut, "/api/v1/namespaces/other/finalize", "update", "api", "", "v1", "other", "namespaces", "finalize", "other", []string{"namespaces", "other", "finalize"}},
{MethodPut, "/api/v1/namespaces/other/status", "update", "api", "", "v1", "other", "namespaces", "status", "other", []string{"namespaces", "other", "status"}},
// verb identification
{"PATCH", "/api/v1/namespaces/other/pods/foo", "patch", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"DELETE", "/api/v1/namespaces/other/pods/foo", "delete", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{"POST", "/api/v1/namespaces/other/pods", "create", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{MethodPatch, "/api/v1/namespaces/other/pods/foo", "patch", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{MethodDelete, "/api/v1/namespaces/other/pods/foo", "delete", "api", "", "v1", "other", "pods", "", "foo", []string{"pods", "foo"}},
{MethodPost, "/api/v1/namespaces/other/pods", "create", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
// deletecollection verb identification
{"DELETE", "/api/v1/nodes", "deletecollection", "api", "", "v1", "", "nodes", "", "", []string{"nodes"}},
{"DELETE", "/api/v1/namespaces", "deletecollection", "api", "", "v1", "", "namespaces", "", "", []string{"namespaces"}},
{"DELETE", "/api/v1/namespaces/other/pods", "deletecollection", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{"DELETE", "/apis/extensions/v1/namespaces/other/pods", "deletecollection", "api", "extensions", "v1", "other", "pods", "", "", []string{"pods"}},
{MethodDelete, "/api/v1/nodes", "deletecollection", "api", "", "v1", "", "nodes", "", "", []string{"nodes"}},
{MethodDelete, "/api/v1/namespaces", "deletecollection", "api", "", "v1", "", "namespaces", "", "", []string{"namespaces"}},
{MethodDelete, "/api/v1/namespaces/other/pods", "deletecollection", "api", "", "v1", "other", "pods", "", "", []string{"pods"}},
{MethodDelete, "/apis/extensions/v1/namespaces/other/pods", "deletecollection", "api", "extensions", "v1", "other", "pods", "", "", []string{"pods"}},
// api group identification
{"POST", "/apis/extensions/v1/namespaces/other/pods", "create", "api", "extensions", "v1", "other", "pods", "", "", []string{"pods"}},
{MethodPost, "/apis/extensions/v1/namespaces/other/pods", "create", "api", "extensions", "v1", "other", "pods", "", "", []string{"pods"}},
// api version identification
{"POST", "/apis/extensions/v1beta3/namespaces/other/pods", "create", "api", "extensions", "v1beta3", "other", "pods", "", "", []string{"pods"}},
{MethodPost, "/apis/extensions/v1beta3/namespaces/other/pods", "create", "api", "extensions", "v1beta3", "other", "pods", "", "", []string{"pods"}},
}
resolver := newTestRequestInfoResolver()
@ -136,7 +136,7 @@ func TestGetAPIRequestInfo(t *testing.T) {
"missing api group": "/apis/version/resource",
}
for k, v := range errorCases {
req, err := http.NewRequest("GET", v, nil)
req, err := http.NewRequest(MethodGet, v, nil)
if err != nil {
t.Errorf("Unexpected error %v", err)
}
@ -174,7 +174,7 @@ func TestGetNonAPIRequestInfo(t *testing.T) {
resolver := newTestRequestInfoResolver()
for testName, tc := range tests {
req, _ := http.NewRequest("GET", tc.url, nil)
req, _ := http.NewRequest(MethodGet, tc.url, nil)
apiRequestInfo, err := resolver.NewRequestInfo(req)
if err != nil {
@ -206,14 +206,14 @@ func TestSelectorParsing(t *testing.T) {
}{
{
name: "no selector",
method: "GET",
method: MethodGet,
url: "/apis/group/version/resource",
expectedVerb: "list",
expectedFieldSelector: "",
},
{
name: "metadata.name selector",
method: "GET",
method: MethodGet,
url: "/apis/group/version/resource?fieldSelector=metadata.name=name1",
expectedName: "name1",
expectedVerb: "list",
@ -221,7 +221,7 @@ func TestSelectorParsing(t *testing.T) {
},
{
name: "metadata.name selector with watch",
method: "GET",
method: MethodGet,
url: "/apis/group/version/resource?watch=true&fieldSelector=metadata.name=name1",
expectedName: "name1",
expectedVerb: "watch",
@ -229,7 +229,7 @@ func TestSelectorParsing(t *testing.T) {
},
{
name: "random selector",
method: "GET",
method: MethodGet,
url: "/apis/group/version/resource?fieldSelector=foo=bar&labelSelector=baz=qux",
expectedName: "",
expectedVerb: "list",
@ -238,7 +238,7 @@ func TestSelectorParsing(t *testing.T) {
},
{
name: "invalid selector with metadata.name",
method: "GET",
method: MethodGet,
url: "/apis/group/version/resource?fieldSelector=metadata.name=name1,foo",
expectedName: "",
expectedErr: fmt.Errorf("invalid selector"),
@ -247,7 +247,7 @@ func TestSelectorParsing(t *testing.T) {
},
{
name: "invalid selector with metadata.name with watch",
method: "GET",
method: MethodGet,
url: "/apis/group/version/resource?fieldSelector=metadata.name=name1,foo&watch=true",
expectedName: "",
expectedErr: fmt.Errorf("invalid selector"),
@ -256,7 +256,7 @@ func TestSelectorParsing(t *testing.T) {
},
{
name: "invalid selector with metadata.name with watch false",
method: "GET",
method: MethodGet,
url: "/apis/group/version/resource?fieldSelector=metadata.name=name1,foo&watch=false",
expectedName: "",
expectedErr: fmt.Errorf("invalid selector"),
@ -265,7 +265,7 @@ func TestSelectorParsing(t *testing.T) {
},
{
name: "selector on deletecollection is honored",
method: "DELETE",
method: MethodDelete,
url: "/apis/group/version/resource?fieldSelector=foo=bar&labelSelector=baz=qux",
expectedName: "",
expectedVerb: "deletecollection",
@ -274,7 +274,7 @@ func TestSelectorParsing(t *testing.T) {
},
{
name: "selector on repeated param matches parsed param",
method: "GET",
method: MethodGet,
url: "/apis/group/version/resource?fieldSelector=metadata.name=foo&fieldSelector=metadata.name=bar&labelSelector=foo=bar&labelSelector=foo=baz",
expectedName: "foo",
expectedVerb: "list",
@ -283,7 +283,7 @@ func TestSelectorParsing(t *testing.T) {
},
{
name: "selector on other verb is ignored",
method: "GET",
method: MethodGet,
url: "/apis/group/version/resource/name?fieldSelector=foo=bar&labelSelector=foo=bar",
expectedName: "name",
expectedVerb: "get",
@ -292,7 +292,7 @@ func TestSelectorParsing(t *testing.T) {
},
{
name: "selector on deprecated root type watch is not parsed",
method: "GET",
method: MethodGet,
url: "/apis/group/version/watch/resource?fieldSelector=metadata.name=foo&labelSelector=foo=bar",
expectedName: "",
expectedVerb: "watch",
@ -301,7 +301,7 @@ func TestSelectorParsing(t *testing.T) {
},
{
name: "selector on deprecated root item watch is not parsed",
method: "GET",
method: MethodGet,
url: "/apis/group/version/watch/resource/name?fieldSelector=metadata.name=foo&labelSelector=foo=bar",
expectedName: "name",
expectedVerb: "watch",

View File

@ -24,6 +24,8 @@ import (
"net/url"
"testing"
"time"
"k8s.io/apiserver/pkg/endpoints/request"
)
func TestWithHTTP1(t *testing.T) {
@ -222,7 +224,7 @@ func newServer(t *testing.T, h http.Handler, http2 bool) *httptest.Server {
}
func sendRequest(t *testing.T, server *httptest.Server) {
req, err := http.NewRequest("GET", server.URL, nil)
req, err := http.NewRequest(request.MethodGet, server.URL, nil)
if err != nil {
t.Fatalf("error creating request: %v", err)
}

View File

@ -41,6 +41,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
"k8s.io/apimachinery/pkg/watch"
example "k8s.io/apiserver/pkg/apis/example"
"k8s.io/apiserver/pkg/endpoints/request"
apitesting "k8s.io/apiserver/pkg/endpoints/testing"
"k8s.io/apiserver/pkg/registry/rest"
)
@ -219,7 +220,7 @@ func TestWatchClientClose(t *testing.T) {
dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simples"
dest.RawQuery = "watch=1"
request, err := http.NewRequest("GET", dest.String(), nil)
request, err := http.NewRequest(request.MethodGet, dest.String(), nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -263,7 +264,7 @@ func TestWatchRead(t *testing.T) {
connectHTTP := func(accept string) (io.ReadCloser, string) {
client := http.Client{}
request, err := http.NewRequest("GET", dest.String(), nil)
request, err := http.NewRequest(request.MethodGet, dest.String(), nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -415,7 +416,7 @@ func TestWatchHTTPAccept(t *testing.T) {
dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simples"
dest.RawQuery = ""
request, err := http.NewRequest("GET", dest.String(), nil)
request, err := http.NewRequest(request.MethodGet, dest.String(), nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -565,7 +566,7 @@ func TestWatchProtocolSelection(t *testing.T) {
}
for _, item := range table {
request, err := http.NewRequest("GET", dest.String(), nil)
request, err := http.NewRequest(request.MethodGet, dest.String(), nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -637,13 +638,13 @@ func runWatchHTTPBenchmark(b *testing.B, items []runtime.Object, contentType str
dest.Path = "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/watch/simples"
dest.RawQuery = ""
request, err := http.NewRequest("GET", dest.String(), nil)
req, err := http.NewRequest(request.MethodGet, dest.String(), nil)
if err != nil {
b.Fatalf("unexpected error: %v", err)
}
request.Header.Add("Accept", contentType)
req.Header.Add("Accept", contentType)
response, err := client.Do(request)
response, err := client.Do(req)
if err != nil {
b.Fatalf("unexpected error: %v", err)
}