Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
6f430741
Commit
6f430741
authored
Jan 12, 2015
by
Daniel Smith
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3404 from smarterclayton/method_not_allowed
Allow RESTStorage objects to not implement methods
parents
c0c7ffb7
455bc176
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
274 additions
and
173 deletions
+274
-173
errors.go
pkg/api/errors/errors.go
+19
-0
errors_test.go
pkg/api/errors/errors_test.go
+12
-0
types.go
pkg/api/types.go
+5
-0
apiserver.go
pkg/apiserver/apiserver.go
+55
-47
apiserver_test.go
pkg/apiserver/apiserver_test.go
+66
-0
interfaces.go
pkg/apiserver/interfaces.go
+16
-1
proxy.go
pkg/apiserver/proxy.go
+2
-1
redirect.go
pkg/apiserver/redirect.go
+2
-1
resthandler.go
pkg/apiserver/resthandler.go
+37
-11
watch.go
pkg/apiserver/watch.go
+26
-24
publish.go
pkg/master/publish.go
+2
-1
rest_to_nodes.go
pkg/master/rest_to_nodes.go
+5
-2
rest.go
pkg/registry/binding/rest.go
+0
-22
rest_test.go
pkg/registry/binding/rest_test.go
+0
-25
rest.go
pkg/registry/controller/rest.go
+4
-0
rest.go
pkg/registry/endpoint/rest.go
+4
-5
rest_test.go
pkg/registry/endpoint/rest_test.go
+0
-11
rest.go
pkg/registry/event/rest.go
+2
-3
rest_test.go
pkg/registry/event/rest_test.go
+0
-14
rest.go
pkg/registry/minion/rest.go
+4
-0
rest.go
pkg/registry/pod/rest.go
+4
-0
rest.go
pkg/registry/service/rest.go
+4
-0
auth_test.go
test/integration/auth_test.go
+5
-5
No files found.
pkg/api/errors/errors.go
View file @
6f430741
...
@@ -159,6 +159,19 @@ func NewBadRequest(reason string) error {
...
@@ -159,6 +159,19 @@ func NewBadRequest(reason string) error {
}}
}}
}
}
// NewMethodNotSupported returns an error indicating the requested action is not supported on this kind.
func
NewMethodNotSupported
(
kind
,
action
string
)
error
{
return
&
StatusError
{
api
.
Status
{
Status
:
api
.
StatusFailure
,
Code
:
http
.
StatusMethodNotAllowed
,
Reason
:
api
.
StatusReasonMethodNotAllowed
,
Details
:
&
api
.
StatusDetails
{
Kind
:
kind
,
},
Message
:
fmt
.
Sprintf
(
"%s is not supported on resources of kind %q"
,
action
,
kind
),
}}
}
// NewInternalError returns an error indicating the item is invalid and cannot be processed.
// NewInternalError returns an error indicating the item is invalid and cannot be processed.
func
NewInternalError
(
err
error
)
error
{
func
NewInternalError
(
err
error
)
error
{
return
&
StatusError
{
api
.
Status
{
return
&
StatusError
{
api
.
Status
{
...
@@ -192,6 +205,12 @@ func IsInvalid(err error) bool {
...
@@ -192,6 +205,12 @@ func IsInvalid(err error) bool {
return
reasonForError
(
err
)
==
api
.
StatusReasonInvalid
return
reasonForError
(
err
)
==
api
.
StatusReasonInvalid
}
}
// IsMethodNotSupported determines if the err is an error which indicates the provided action could not
// be performed because it is not supported by the server.
func
IsMethodNotSupported
(
err
error
)
bool
{
return
reasonForError
(
err
)
==
api
.
StatusReasonMethodNotAllowed
}
// IsBadRequest determines if err is an error which indicates that the request is invalid.
// IsBadRequest determines if err is an error which indicates that the request is invalid.
func
IsBadRequest
(
err
error
)
bool
{
func
IsBadRequest
(
err
error
)
bool
{
return
reasonForError
(
err
)
==
api
.
StatusReasonBadRequest
return
reasonForError
(
err
)
==
api
.
StatusReasonBadRequest
...
...
pkg/api/errors/errors_test.go
View file @
6f430741
...
@@ -40,6 +40,12 @@ func TestErrorNew(t *testing.T) {
...
@@ -40,6 +40,12 @@ func TestErrorNew(t *testing.T) {
if
IsInvalid
(
err
)
{
if
IsInvalid
(
err
)
{
t
.
Errorf
(
"expected to not be %s"
,
api
.
StatusReasonInvalid
)
t
.
Errorf
(
"expected to not be %s"
,
api
.
StatusReasonInvalid
)
}
}
if
IsBadRequest
(
err
)
{
t
.
Errorf
(
"expected to not be %s"
,
api
.
StatusReasonBadRequest
)
}
if
IsMethodNotSupported
(
err
)
{
t
.
Errorf
(
"expected to not be %s"
,
api
.
StatusReasonMethodNotAllowed
)
}
if
!
IsConflict
(
NewConflict
(
"test"
,
"2"
,
errors
.
New
(
"message"
)))
{
if
!
IsConflict
(
NewConflict
(
"test"
,
"2"
,
errors
.
New
(
"message"
)))
{
t
.
Errorf
(
"expected to be conflict"
)
t
.
Errorf
(
"expected to be conflict"
)
...
@@ -50,6 +56,12 @@ func TestErrorNew(t *testing.T) {
...
@@ -50,6 +56,12 @@ func TestErrorNew(t *testing.T) {
if
!
IsInvalid
(
NewInvalid
(
"test"
,
"2"
,
nil
))
{
if
!
IsInvalid
(
NewInvalid
(
"test"
,
"2"
,
nil
))
{
t
.
Errorf
(
"expected to be %s"
,
api
.
StatusReasonInvalid
)
t
.
Errorf
(
"expected to be %s"
,
api
.
StatusReasonInvalid
)
}
}
if
!
IsBadRequest
(
NewBadRequest
(
"reason"
))
{
t
.
Errorf
(
"expected to be %s"
,
api
.
StatusReasonBadRequest
)
}
if
!
IsMethodNotSupported
(
NewMethodNotSupported
(
"foo"
,
"delete"
))
{
t
.
Errorf
(
"expected to be %s"
,
api
.
StatusReasonMethodNotAllowed
)
}
}
}
func
TestNewInvalid
(
t
*
testing
.
T
)
{
func
TestNewInvalid
(
t
*
testing
.
T
)
{
...
...
pkg/api/types.go
View file @
6f430741
...
@@ -931,6 +931,11 @@ const (
...
@@ -931,6 +931,11 @@ const (
// data was invalid. API calls that return BadRequest can never succeed.
// data was invalid. API calls that return BadRequest can never succeed.
StatusReasonBadRequest
StatusReason
=
"BadRequest"
StatusReasonBadRequest
StatusReason
=
"BadRequest"
// StatusReasonMethodNotAllowed means that the action the client attempted to perform on the
// resource was not supported by the code - for instance, attempting to delete a resource that
// can only be created. API calls that return MethodNotAllowed can never succeed.
StatusReasonMethodNotAllowed
StatusReason
=
"MethodNotAllowed"
// StatusReasonInternalError indicates that an internal error occurred, it is unexpected
// StatusReasonInternalError indicates that an internal error occurred, it is unexpected
// and the outcome of the call is unknown.
// and the outcome of the call is unknown.
// Details (optional):
// Details (optional):
...
...
pkg/apiserver/apiserver.go
View file @
6f430741
...
@@ -129,62 +129,70 @@ func registerResourceHandlers(ws *restful.WebService, version string, path strin
...
@@ -129,62 +129,70 @@ func registerResourceHandlers(ws *restful.WebService, version string, path strin
nameParam
:=
ws
.
PathParameter
(
"name"
,
"name of the "
+
kind
)
.
DataType
(
"string"
)
nameParam
:=
ws
.
PathParameter
(
"name"
,
"name of the "
+
kind
)
.
DataType
(
"string"
)
namespaceParam
:=
ws
.
PathParameter
(
"namespace"
,
"object name and auth scope, such as for teams and projects"
)
.
DataType
(
"string"
)
namespaceParam
:=
ws
.
PathParameter
(
"namespace"
,
"object name and auth scope, such as for teams and projects"
)
.
DataType
(
"string"
)
ws
.
Route
(
createRoute
:=
ws
.
POST
(
path
)
.
To
(
h
)
.
addParamIf
(
Doc
(
"create a "
+
kind
)
.
ws
.
POST
(
path
)
.
To
(
h
)
.
Operation
(
"create"
+
kind
)
.
Doc
(
"create a "
+
kind
)
.
Reads
(
versionedObject
)
// from the request
Operation
(
"create"
+
kind
)
.
addParamIf
(
createRoute
,
namespaceParam
,
namespaceScope
)
Reads
(
versionedObject
),
// from the request
if
_
,
ok
:=
storage
.
(
RESTCreater
);
ok
{
namespaceParam
,
namespaceScope
))
ws
.
Route
(
createRoute
.
Reads
(
versionedObject
))
// from the request
// TODO: This seems like a hack. Add NewList() to storage?
listKind
:=
kind
+
"List"
if
_
,
ok
:=
kinds
[
listKind
];
!
ok
{
glog
.
V
(
1
)
.
Infof
(
"no list type: %v
\n
"
,
listKind
)
}
else
{
}
else
{
ws
.
Route
(
createRoute
.
Returns
(
http
.
StatusMethodNotAllowed
,
"creating objects is not supported"
,
nil
))
}
listRoute
:=
ws
.
GET
(
path
)
.
To
(
h
)
.
Doc
(
"list objects of kind "
+
kind
)
.
Operation
(
"list"
+
kind
)
addParamIf
(
listRoute
,
namespaceParam
,
namespaceScope
)
if
lister
,
ok
:=
storage
.
(
RESTLister
);
ok
{
list
:=
lister
.
NewList
()
_
,
listKind
,
err
:=
api
.
Scheme
.
ObjectVersionAndKind
(
list
)
versionedListPtr
,
err
:=
api
.
Scheme
.
New
(
version
,
listKind
)
versionedListPtr
,
err
:=
api
.
Scheme
.
New
(
version
,
listKind
)
if
err
!=
nil
{
if
err
!=
nil
{
glog
.
Errorf
(
"error making list: %v
\n
"
,
err
)
glog
.
Errorf
(
"error making list object: %v
\n
"
,
err
)
}
else
{
return
versionedList
:=
indirectArbitraryPointer
(
versionedListPtr
)
glog
.
V
(
3
)
.
Infoln
(
"type: "
,
reflect
.
TypeOf
(
versionedList
))
ws
.
Route
(
addParamIf
(
ws
.
GET
(
path
)
.
To
(
h
)
.
Doc
(
"list objects of kind "
+
kind
)
.
Operation
(
"list"
+
kind
)
.
Returns
(
http
.
StatusOK
,
"OK"
,
versionedList
),
namespaceParam
,
namespaceScope
))
}
}
versionedList
:=
indirectArbitraryPointer
(
versionedListPtr
)
glog
.
V
(
3
)
.
Infoln
(
"type: "
,
reflect
.
TypeOf
(
versionedList
))
ws
.
Route
(
listRoute
.
Returns
(
http
.
StatusOK
,
"OK"
,
versionedList
))
}
else
{
ws
.
Route
(
listRoute
.
Returns
(
http
.
StatusMethodNotAllowed
,
"listing objects is not supported"
,
nil
))
}
}
ws
.
Route
(
getRoute
:=
ws
.
GET
(
path
+
"/{name}"
)
.
To
(
h
)
.
addParamIf
(
Doc
(
"read the specified "
+
kind
)
.
ws
.
GET
(
path
+
"/{name}"
)
.
To
(
h
)
.
Operation
(
"read"
+
kind
)
.
Doc
(
"read the specified "
+
kind
)
.
Param
(
nameParam
)
Operation
(
"read"
+
kind
)
.
addParamIf
(
getRoute
,
namespaceParam
,
namespaceScope
)
Param
(
nameParam
)
.
if
_
,
ok
:=
storage
.
(
RESTGetter
);
ok
{
Writes
(
versionedObject
),
// on the response
ws
.
Route
(
getRoute
.
Writes
(
versionedObject
))
// on the response
namespaceParam
,
namespaceScope
))
}
else
{
ws
.
Route
(
ws
.
GET
(
path
+
"/{name}"
)
.
To
(
h
)
.
Returns
(
http
.
StatusMethodNotAllowed
,
"reading individual objects is not supported"
,
nil
))
}
ws
.
Route
(
updateRoute
:=
ws
.
PUT
(
path
+
"/{name}"
)
.
To
(
h
)
.
addParamIf
(
Doc
(
"update the specified "
+
kind
)
.
ws
.
PUT
(
path
+
"/{name}"
)
.
To
(
h
)
.
Operation
(
"update"
+
kind
)
.
Doc
(
"update the specified "
+
kind
)
.
Param
(
nameParam
)
Operation
(
"update"
+
kind
)
.
addParamIf
(
updateRoute
,
namespaceParam
,
namespaceScope
)
Param
(
nameParam
)
.
if
_
,
ok
:=
storage
.
(
RESTUpdater
);
ok
{
Reads
(
versionedObject
),
// from the request
ws
.
Route
(
updateRoute
.
Reads
(
versionedObject
))
// from the request
namespaceParam
,
namespaceScope
))
}
else
{
ws
.
Route
(
updateRoute
.
Returns
(
http
.
StatusMethodNotAllowed
,
"updating objects is not supported"
,
nil
))
}
// TODO: Support PATCH
// TODO: Support PATCH
deleteRoute
:=
ws
.
DELETE
(
path
+
"/{name}"
)
.
To
(
h
)
.
ws
.
Route
(
Doc
(
"delete the specified "
+
kind
)
.
addParamIf
(
Operation
(
"delete"
+
kind
)
.
ws
.
DELETE
(
path
+
"/{name}"
)
.
To
(
h
)
.
Param
(
nameParam
)
Doc
(
"delete the specified "
+
kind
)
.
addParamIf
(
deleteRoute
,
namespaceParam
,
namespaceScope
)
Operation
(
"delete"
+
kind
)
.
if
_
,
ok
:=
storage
.
(
RESTDeleter
);
ok
{
Param
(
nameParam
),
ws
.
Route
(
deleteRoute
)
namespaceParam
,
namespaceScope
))
}
else
{
ws
.
Route
(
deleteRoute
.
Returns
(
http
.
StatusMethodNotAllowed
,
"deleting objects is not supported"
,
nil
))
}
}
}
// Adds the given param to the given route builder if shouldAdd is true. Does nothing if shouldAdd is false.
// Adds the given param to the given route builder if shouldAdd is true. Does nothing if shouldAdd is false.
...
...
pkg/apiserver/apiserver_test.go
View file @
6f430741
...
@@ -183,6 +183,10 @@ func (storage *SimpleRESTStorage) New() runtime.Object {
...
@@ -183,6 +183,10 @@ func (storage *SimpleRESTStorage) New() runtime.Object {
return
&
Simple
{}
return
&
Simple
{}
}
}
func
(
storage
*
SimpleRESTStorage
)
NewList
()
runtime
.
Object
{
return
&
SimpleList
{}
}
func
(
storage
*
SimpleRESTStorage
)
Create
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
RESTResult
,
error
)
{
func
(
storage
*
SimpleRESTStorage
)
Create
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
RESTResult
,
error
)
{
storage
.
created
=
obj
.
(
*
Simple
)
storage
.
created
=
obj
.
(
*
Simple
)
if
err
:=
storage
.
errors
[
"create"
];
err
!=
nil
{
if
err
:=
storage
.
errors
[
"create"
];
err
!=
nil
{
...
@@ -288,6 +292,68 @@ func TestNotFound(t *testing.T) {
...
@@ -288,6 +292,68 @@ func TestNotFound(t *testing.T) {
}
}
}
}
type
UnimplementedRESTStorage
struct
{}
func
(
UnimplementedRESTStorage
)
New
()
runtime
.
Object
{
return
&
Simple
{}
}
func
TestMethodNotAllowed
(
t
*
testing
.
T
)
{
type
T
struct
{
Method
string
Path
string
}
cases
:=
map
[
string
]
T
{
"GET object"
:
{
"GET"
,
"/prefix/version/foo/bar"
},
"GET list"
:
{
"GET"
,
"/prefix/version/foo"
},
"POST list"
:
{
"POST"
,
"/prefix/version/foo"
},
"PUT object"
:
{
"PUT"
,
"/prefix/version/foo/bar"
},
"DELETE object"
:
{
"DELETE"
,
"/prefix/version/foo/bar"
},
//"watch list": {"GET", "/prefix/version/watch/foo"},
//"watch object": {"GET", "/prefix/version/watch/foo/bar"},
"proxy object"
:
{
"GET"
,
"/prefix/version/proxy/foo/bar"
},
"redirect object"
:
{
"GET"
,
"/prefix/version/redirect/foo/bar"
},
}
handler
:=
Handle
(
map
[
string
]
RESTStorage
{
"foo"
:
UnimplementedRESTStorage
{},
},
codec
,
"/prefix"
,
testVersion
,
selfLinker
,
admissionControl
)
server
:=
httptest
.
NewServer
(
handler
)
defer
server
.
Close
()
client
:=
http
.
Client
{}
for
k
,
v
:=
range
cases
{
request
,
err
:=
http
.
NewRequest
(
v
.
Method
,
server
.
URL
+
v
.
Path
,
bytes
.
NewReader
([]
byte
(
`{"kind":"Simple","apiVersion":"version"}`
)))
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
response
,
err
:=
client
.
Do
(
request
)
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
continue
}
defer
response
.
Body
.
Close
()
data
,
_
:=
ioutil
.
ReadAll
(
response
.
Body
)
t
.
Logf
(
"resp: %s"
,
string
(
data
))
if
response
.
StatusCode
!=
http
.
StatusMethodNotAllowed
{
t
.
Errorf
(
"%s: expected %d for %s, Got %s"
,
k
,
http
.
StatusMethodNotAllowed
,
v
.
Method
,
string
(
data
))
continue
}
obj
,
err
:=
codec
.
Decode
(
data
)
if
err
!=
nil
{
t
.
Errorf
(
"%s: unexpected decode error: %v"
,
k
,
err
)
continue
}
status
,
ok
:=
obj
.
(
*
api
.
Status
)
if
!
ok
{
t
.
Errorf
(
"%s: unexpected object: %#v"
,
k
,
obj
)
continue
}
if
status
.
Reason
!=
api
.
StatusReasonMethodNotAllowed
{
t
.
Errorf
(
"%s: unexpected status: %#v"
,
k
,
status
)
}
}
}
func
TestVersion
(
t
*
testing
.
T
)
{
func
TestVersion
(
t
*
testing
.
T
)
{
handler
:=
Handle
(
map
[
string
]
RESTStorage
{},
codec
,
"/prefix"
,
testVersion
,
selfLinker
,
admissionControl
)
handler
:=
Handle
(
map
[
string
]
RESTStorage
{},
codec
,
"/prefix"
,
testVersion
,
selfLinker
,
admissionControl
)
server
:=
httptest
.
NewServer
(
handler
)
server
:=
httptest
.
NewServer
(
handler
)
...
...
pkg/apiserver/interfaces.go
View file @
6f430741
...
@@ -24,28 +24,43 @@ import (
...
@@ -24,28 +24,43 @@ import (
)
)
// RESTStorage is a generic interface for RESTful storage services.
// RESTStorage is a generic interface for RESTful storage services.
// Resources which are exported to the RESTful API of apiserver need to implement this interface.
// Resources which are exported to the RESTful API of apiserver need to implement this interface. It is expected
// that objects may implement any of the REST* interfaces.
// TODO: implement dynamic introspection (so GenericREST objects can indicate what they implement)
type
RESTStorage
interface
{
type
RESTStorage
interface
{
// New returns an empty object that can be used with Create and Update after request data has been put into it.
// New returns an empty object that can be used with Create and Update after request data has been put into it.
// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
New
()
runtime
.
Object
New
()
runtime
.
Object
}
type
RESTLister
interface
{
// NewList returns an empty object that can be used with the List call.
// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
NewList
()
runtime
.
Object
// List selects resources in the storage which match to the selector.
// List selects resources in the storage which match to the selector.
List
(
ctx
api
.
Context
,
label
,
field
labels
.
Selector
)
(
runtime
.
Object
,
error
)
List
(
ctx
api
.
Context
,
label
,
field
labels
.
Selector
)
(
runtime
.
Object
,
error
)
}
type
RESTGetter
interface
{
// Get finds a resource in the storage by id and returns it.
// Get finds a resource in the storage by id and returns it.
// Although it can return an arbitrary error value, IsNotFound(err) is true for the
// Although it can return an arbitrary error value, IsNotFound(err) is true for the
// returned error value err when the specified resource is not found.
// returned error value err when the specified resource is not found.
Get
(
ctx
api
.
Context
,
id
string
)
(
runtime
.
Object
,
error
)
Get
(
ctx
api
.
Context
,
id
string
)
(
runtime
.
Object
,
error
)
}
type
RESTDeleter
interface
{
// Delete finds a resource in the storage and deletes it.
// Delete finds a resource in the storage and deletes it.
// Although it can return an arbitrary error value, IsNotFound(err) is true for the
// Although it can return an arbitrary error value, IsNotFound(err) is true for the
// returned error value err when the specified resource is not found.
// returned error value err when the specified resource is not found.
Delete
(
ctx
api
.
Context
,
id
string
)
(
<-
chan
RESTResult
,
error
)
Delete
(
ctx
api
.
Context
,
id
string
)
(
<-
chan
RESTResult
,
error
)
}
type
RESTCreater
interface
{
// Create creates a new version of a resource.
// Create creates a new version of a resource.
Create
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
RESTResult
,
error
)
Create
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
RESTResult
,
error
)
}
type
RESTUpdater
interface
{
// Update finds a resource in the storage and updates it. Some implementations
// Update finds a resource in the storage and updates it. Some implementations
// may allow updates creates the object - they should set the Created flag of
// may allow updates creates the object - they should set the Created flag of
// the returned RESTResultto true. In the event of an asynchronous error returned
// the returned RESTResultto true. In the event of an asynchronous error returned
...
...
pkg/apiserver/proxy.go
View file @
6f430741
...
@@ -30,6 +30,7 @@ import (
...
@@ -30,6 +30,7 @@ import (
"time"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
...
@@ -106,7 +107,7 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
...
@@ -106,7 +107,7 @@ func (r *ProxyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
redirector
,
ok
:=
storage
.
(
Redirector
)
redirector
,
ok
:=
storage
.
(
Redirector
)
if
!
ok
{
if
!
ok
{
httplog
.
LogOf
(
req
,
w
)
.
Addf
(
"'%v' is not a redirector"
,
kind
)
httplog
.
LogOf
(
req
,
w
)
.
Addf
(
"'%v' is not a redirector"
,
kind
)
notFound
(
w
,
req
)
errorJSON
(
errors
.
NewMethodNotSupported
(
kind
,
"proxy"
),
r
.
codec
,
w
)
return
return
}
}
...
...
pkg/apiserver/redirect.go
View file @
6f430741
...
@@ -20,6 +20,7 @@ import (
...
@@ -20,6 +20,7 @@ import (
"net/http"
"net/http"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
)
...
@@ -53,7 +54,7 @@ func (r *RedirectHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
...
@@ -53,7 +54,7 @@ func (r *RedirectHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
redirector
,
ok
:=
storage
.
(
Redirector
)
redirector
,
ok
:=
storage
.
(
Redirector
)
if
!
ok
{
if
!
ok
{
httplog
.
LogOf
(
req
,
w
)
.
Addf
(
"'%v' is not a redirector"
,
kind
)
httplog
.
LogOf
(
req
,
w
)
.
Addf
(
"'%v' is not a redirector"
,
kind
)
notFound
(
w
,
req
)
errorJSON
(
errors
.
NewMethodNotSupported
(
kind
,
"redirect"
),
r
.
codec
,
w
)
return
return
}
}
...
...
pkg/apiserver/resthandler.go
View file @
6f430741
...
@@ -23,7 +23,7 @@ import (
...
@@ -23,7 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/
httplog
"
"github.com/GoogleCloudPlatform/kubernetes/pkg/
api/errors
"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
...
@@ -48,14 +48,13 @@ func (h *RESTHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
...
@@ -48,14 +48,13 @@ func (h *RESTHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
notFound
(
w
,
req
)
notFound
(
w
,
req
)
return
return
}
}
storage
:=
h
.
storage
[
kind
]
storage
,
ok
:=
h
.
storage
[
kind
]
if
storage
==
nil
{
if
!
ok
{
httplog
.
LogOf
(
req
,
w
)
.
Addf
(
"'%v' has no storage object"
,
kind
)
notFound
(
w
,
req
)
notFound
(
w
,
req
)
return
return
}
}
h
.
handleRESTStorage
(
parts
,
req
,
w
,
storage
,
namespace
)
h
.
handleRESTStorage
(
parts
,
req
,
w
,
storage
,
namespace
,
kind
)
}
}
// Sets the SelfLink field of the object.
// Sets the SelfLink field of the object.
...
@@ -148,7 +147,7 @@ func curry(f func(runtime.Object, *http.Request) error, req *http.Request) func(
...
@@ -148,7 +147,7 @@ func curry(f func(runtime.Object, *http.Request) error, req *http.Request) func(
// sync=[false|true] Synchronous request (only applies to create, update, delete operations)
// sync=[false|true] Synchronous request (only applies to create, update, delete operations)
// timeout=<duration> Timeout for synchronous requests, only applies if sync=true
// timeout=<duration> Timeout for synchronous requests, only applies if sync=true
// labels=<label-selector> Used for filtering list operations
// labels=<label-selector> Used for filtering list operations
func
(
h
*
RESTHandler
)
handleRESTStorage
(
parts
[]
string
,
req
*
http
.
Request
,
w
http
.
ResponseWriter
,
storage
RESTStorage
,
namespace
string
)
{
func
(
h
*
RESTHandler
)
handleRESTStorage
(
parts
[]
string
,
req
*
http
.
Request
,
w
http
.
ResponseWriter
,
storage
RESTStorage
,
namespace
,
kind
string
)
{
ctx
:=
api
.
WithNamespace
(
api
.
NewContext
(),
namespace
)
ctx
:=
api
.
WithNamespace
(
api
.
NewContext
(),
namespace
)
sync
:=
req
.
URL
.
Query
()
.
Get
(
"sync"
)
==
"true"
sync
:=
req
.
URL
.
Query
()
.
Get
(
"sync"
)
==
"true"
timeout
:=
parseTimeout
(
req
.
URL
.
Query
()
.
Get
(
"timeout"
))
timeout
:=
parseTimeout
(
req
.
URL
.
Query
()
.
Get
(
"timeout"
))
...
@@ -166,7 +165,12 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
...
@@ -166,7 +165,12 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
errorJSON
(
err
,
h
.
codec
,
w
)
errorJSON
(
err
,
h
.
codec
,
w
)
return
return
}
}
list
,
err
:=
storage
.
List
(
ctx
,
label
,
field
)
lister
,
ok
:=
storage
.
(
RESTLister
)
if
!
ok
{
errorJSON
(
errors
.
NewMethodNotSupported
(
kind
,
"list"
),
h
.
codec
,
w
)
return
}
list
,
err
:=
lister
.
List
(
ctx
,
label
,
field
)
if
err
!=
nil
{
if
err
!=
nil
{
errorJSON
(
err
,
h
.
codec
,
w
)
errorJSON
(
err
,
h
.
codec
,
w
)
return
return
...
@@ -177,7 +181,12 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
...
@@ -177,7 +181,12 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
}
}
writeJSON
(
http
.
StatusOK
,
h
.
codec
,
list
,
w
)
writeJSON
(
http
.
StatusOK
,
h
.
codec
,
list
,
w
)
case
2
:
case
2
:
item
,
err
:=
storage
.
Get
(
ctx
,
parts
[
1
])
getter
,
ok
:=
storage
.
(
RESTGetter
)
if
!
ok
{
errorJSON
(
errors
.
NewMethodNotSupported
(
kind
,
"get"
),
h
.
codec
,
w
)
return
}
item
,
err
:=
getter
.
Get
(
ctx
,
parts
[
1
])
if
err
!=
nil
{
if
err
!=
nil
{
errorJSON
(
err
,
h
.
codec
,
w
)
errorJSON
(
err
,
h
.
codec
,
w
)
return
return
...
@@ -196,6 +205,12 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
...
@@ -196,6 +205,12 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
notFound
(
w
,
req
)
notFound
(
w
,
req
)
return
return
}
}
creater
,
ok
:=
storage
.
(
RESTCreater
)
if
!
ok
{
errorJSON
(
errors
.
NewMethodNotSupported
(
kind
,
"create"
),
h
.
codec
,
w
)
return
}
body
,
err
:=
readBody
(
req
)
body
,
err
:=
readBody
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
errorJSON
(
err
,
h
.
codec
,
w
)
errorJSON
(
err
,
h
.
codec
,
w
)
...
@@ -215,7 +230,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
...
@@ -215,7 +230,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
return
return
}
}
out
,
err
:=
storage
.
Create
(
ctx
,
obj
)
out
,
err
:=
creater
.
Create
(
ctx
,
obj
)
if
err
!=
nil
{
if
err
!=
nil
{
errorJSON
(
err
,
h
.
codec
,
w
)
errorJSON
(
err
,
h
.
codec
,
w
)
return
return
...
@@ -228,6 +243,11 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
...
@@ -228,6 +243,11 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
notFound
(
w
,
req
)
notFound
(
w
,
req
)
return
return
}
}
deleter
,
ok
:=
storage
.
(
RESTDeleter
)
if
!
ok
{
errorJSON
(
errors
.
NewMethodNotSupported
(
kind
,
"delete"
),
h
.
codec
,
w
)
return
}
// invoke admission control
// invoke admission control
err
:=
h
.
admissionControl
.
Admit
(
admission
.
NewAttributesRecord
(
nil
,
namespace
,
parts
[
0
],
"DELETE"
))
err
:=
h
.
admissionControl
.
Admit
(
admission
.
NewAttributesRecord
(
nil
,
namespace
,
parts
[
0
],
"DELETE"
))
...
@@ -236,7 +256,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
...
@@ -236,7 +256,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
return
return
}
}
out
,
err
:=
storage
.
Delete
(
ctx
,
parts
[
1
])
out
,
err
:=
deleter
.
Delete
(
ctx
,
parts
[
1
])
if
err
!=
nil
{
if
err
!=
nil
{
errorJSON
(
err
,
h
.
codec
,
w
)
errorJSON
(
err
,
h
.
codec
,
w
)
return
return
...
@@ -249,6 +269,12 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
...
@@ -249,6 +269,12 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
notFound
(
w
,
req
)
notFound
(
w
,
req
)
return
return
}
}
updater
,
ok
:=
storage
.
(
RESTUpdater
)
if
!
ok
{
errorJSON
(
errors
.
NewMethodNotSupported
(
kind
,
"create"
),
h
.
codec
,
w
)
return
}
body
,
err
:=
readBody
(
req
)
body
,
err
:=
readBody
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
errorJSON
(
err
,
h
.
codec
,
w
)
errorJSON
(
err
,
h
.
codec
,
w
)
...
@@ -268,7 +294,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
...
@@ -268,7 +294,7 @@ func (h *RESTHandler) handleRESTStorage(parts []string, req *http.Request, w htt
return
return
}
}
out
,
err
:=
storage
.
Update
(
ctx
,
obj
)
out
,
err
:=
updater
.
Update
(
ctx
,
obj
)
if
err
!=
nil
{
if
err
!=
nil
{
errorJSON
(
err
,
h
.
codec
,
w
)
errorJSON
(
err
,
h
.
codec
,
w
)
return
return
...
...
pkg/apiserver/watch.go
View file @
6f430741
...
@@ -24,6 +24,7 @@ import (
...
@@ -24,6 +24,7 @@ import (
"strings"
"strings"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
...
@@ -98,34 +99,35 @@ func (h *WatchHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
...
@@ -98,34 +99,35 @@ func (h *WatchHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
notFound
(
w
,
req
)
notFound
(
w
,
req
)
return
return
}
}
if
watcher
,
ok
:=
storage
.
(
ResourceWatcher
);
ok
{
watcher
,
ok
:=
storage
.
(
ResourceWatcher
)
label
,
field
,
resourceVersion
,
err
:=
getWatchParams
(
req
.
URL
.
Query
())
if
!
ok
{
if
err
!=
nil
{
errorJSON
(
errors
.
NewMethodNotSupported
(
kind
,
"watch"
),
h
.
codec
,
w
)
errorJSON
(
err
,
h
.
codec
,
w
)
return
return
}
}
watching
,
err
:=
watcher
.
Watch
(
ctx
,
label
,
field
,
resourceVersion
)
if
err
!=
nil
{
errorJSON
(
err
,
h
.
codec
,
w
)
return
}
// TODO: This is one watch per connection. We want to multiplex, so that
label
,
field
,
resourceVersion
,
err
:=
getWatchParams
(
req
.
URL
.
Query
())
// multiple watches of the same thing don't create two watches downstream.
if
err
!=
nil
{
watchServer
:=
&
WatchServer
{
watching
,
h
.
codec
,
func
(
obj
runtime
.
Object
)
{
errorJSON
(
err
,
h
.
codec
,
w
)
if
err
:=
h
.
setSelfLinkAddName
(
obj
,
req
);
err
!=
nil
{
return
glog
.
Errorf
(
"Failed to set self link for object %#v"
,
obj
)
}
}
watching
,
err
:=
watcher
.
Watch
(
ctx
,
label
,
field
,
resourceVersion
)
}}
if
err
!=
nil
{
if
isWebsocketRequest
(
req
)
{
errorJSON
(
err
,
h
.
codec
,
w
)
websocket
.
Handler
(
watchServer
.
HandleWS
)
.
ServeHTTP
(
httplog
.
Unlogged
(
w
),
req
)
}
else
{
watchServer
.
ServeHTTP
(
w
,
req
)
}
return
return
}
}
notFound
(
w
,
req
)
// TODO: This is one watch per connection. We want to multiplex, so that
// multiple watches of the same thing don't create two watches downstream.
watchServer
:=
&
WatchServer
{
watching
,
h
.
codec
,
func
(
obj
runtime
.
Object
)
{
if
err
:=
h
.
setSelfLinkAddName
(
obj
,
req
);
err
!=
nil
{
glog
.
Errorf
(
"Failed to set self link for object %#v"
,
obj
)
}
}}
if
isWebsocketRequest
(
req
)
{
websocket
.
Handler
(
watchServer
.
HandleWS
)
.
ServeHTTP
(
httplog
.
Unlogged
(
w
),
req
)
}
else
{
watchServer
.
ServeHTTP
(
w
,
req
)
}
}
}
// WatchServer serves a watch.Interface over a websocket or vanilla HTTP.
// WatchServer serves a watch.Interface over a websocket or vanilla HTTP.
...
...
pkg/master/publish.go
View file @
6f430741
...
@@ -21,6 +21,7 @@ import (
...
@@ -21,6 +21,7 @@ import (
"time"
"time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/golang/glog"
"github.com/golang/glog"
)
)
...
@@ -94,7 +95,7 @@ func (m *Master) createMasterServiceIfNeeded(serviceName string, port int) error
...
@@ -94,7 +95,7 @@ func (m *Master) createMasterServiceIfNeeded(serviceName string, port int) error
}
}
// Kids, don't do this at home: this is a hack. There's no good way to call the business
// Kids, don't do this at home: this is a hack. There's no good way to call the business
// logic which lives in the REST object from here.
// logic which lives in the REST object from here.
c
,
err
:=
m
.
storage
[
"services"
]
.
Create
(
ctx
,
svc
)
c
,
err
:=
m
.
storage
[
"services"
]
.
(
apiserver
.
RESTCreater
)
.
Create
(
ctx
,
svc
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
...
pkg/master/rest_to_nodes.go
View file @
6f430741
...
@@ -33,6 +33,9 @@ import (
...
@@ -33,6 +33,9 @@ import (
// TODO: considering that the only difference between the various client types
// TODO: considering that the only difference between the various client types
// and RESTStorage type is the type of the arguments, maybe use "go generate" to
// and RESTStorage type is the type of the arguments, maybe use "go generate" to
// write a specialized adaptor for every client type?
// write a specialized adaptor for every client type?
//
// TODO: this also means that pod and node API endpoints have to be colocated in the same
// process
func
RESTStorageToNodes
(
storage
apiserver
.
RESTStorage
)
client
.
NodesInterface
{
func
RESTStorageToNodes
(
storage
apiserver
.
RESTStorage
)
client
.
NodesInterface
{
return
&
nodeAdaptor
{
storage
}
return
&
nodeAdaptor
{
storage
}
}
}
...
@@ -61,7 +64,7 @@ func (n *nodeAdaptor) Create(minion *api.Node) (*api.Node, error) {
...
@@ -61,7 +64,7 @@ func (n *nodeAdaptor) Create(minion *api.Node) (*api.Node, error) {
// List lists all the nodes in the cluster.
// List lists all the nodes in the cluster.
func
(
n
*
nodeAdaptor
)
List
()
(
*
api
.
NodeList
,
error
)
{
func
(
n
*
nodeAdaptor
)
List
()
(
*
api
.
NodeList
,
error
)
{
ctx
:=
api
.
NewContext
()
ctx
:=
api
.
NewContext
()
obj
,
err
:=
n
.
storage
.
List
(
ctx
,
labels
.
Everything
(),
labels
.
Everything
())
obj
,
err
:=
n
.
storage
.
(
apiserver
.
RESTLister
)
.
List
(
ctx
,
labels
.
Everything
(),
labels
.
Everything
())
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -71,7 +74,7 @@ func (n *nodeAdaptor) List() (*api.NodeList, error) {
...
@@ -71,7 +74,7 @@ func (n *nodeAdaptor) List() (*api.NodeList, error) {
// Get gets an existing minion
// Get gets an existing minion
func
(
n
*
nodeAdaptor
)
Get
(
name
string
)
(
*
api
.
Node
,
error
)
{
func
(
n
*
nodeAdaptor
)
Get
(
name
string
)
(
*
api
.
Node
,
error
)
{
ctx
:=
api
.
NewContext
()
ctx
:=
api
.
NewContext
()
obj
,
err
:=
n
.
storage
.
Get
(
ctx
,
name
)
obj
,
err
:=
n
.
storage
.
(
apiserver
.
RESTGetter
)
.
Get
(
ctx
,
name
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
pkg/registry/binding/rest.go
View file @
6f430741
...
@@ -20,9 +20,7 @@ import (
...
@@ -20,9 +20,7 @@ import (
"fmt"
"fmt"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
)
)
...
@@ -40,21 +38,6 @@ func NewREST(bindingRegistry Registry) *REST {
...
@@ -40,21 +38,6 @@ func NewREST(bindingRegistry Registry) *REST {
}
}
}
}
// List returns an error because bindings are write-only objects.
func
(
*
REST
)
List
(
ctx
api
.
Context
,
label
,
field
labels
.
Selector
)
(
runtime
.
Object
,
error
)
{
return
nil
,
errors
.
NewNotFound
(
"binding"
,
"list"
)
}
// Get returns an error because bindings are write-only objects.
func
(
*
REST
)
Get
(
ctx
api
.
Context
,
id
string
)
(
runtime
.
Object
,
error
)
{
return
nil
,
errors
.
NewNotFound
(
"binding"
,
id
)
}
// Delete returns an error because bindings are write-only objects.
func
(
*
REST
)
Delete
(
ctx
api
.
Context
,
id
string
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
return
nil
,
errors
.
NewNotFound
(
"binding"
,
id
)
}
// New returns a new binding object fit for having data unmarshalled into it.
// New returns a new binding object fit for having data unmarshalled into it.
func
(
*
REST
)
New
()
runtime
.
Object
{
func
(
*
REST
)
New
()
runtime
.
Object
{
return
&
api
.
Binding
{}
return
&
api
.
Binding
{}
...
@@ -73,8 +56,3 @@ func (b *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RES
...
@@ -73,8 +56,3 @@ func (b *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RES
return
&
api
.
Status
{
Status
:
api
.
StatusSuccess
},
nil
return
&
api
.
Status
{
Status
:
api
.
StatusSuccess
},
nil
}),
nil
}),
nil
}
}
// Update returns an error-- this object may not be updated.
func
(
b
*
REST
)
Update
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
return
nil
,
fmt
.
Errorf
(
"bindings may not be changed."
)
}
pkg/registry/binding/rest_test.go
View file @
6f430741
...
@@ -24,7 +24,6 @@ import (
...
@@ -24,7 +24,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
)
)
func
TestNewREST
(
t
*
testing
.
T
)
{
func
TestNewREST
(
t
*
testing
.
T
)
{
...
@@ -51,30 +50,6 @@ func TestNewREST(t *testing.T) {
...
@@ -51,30 +50,6 @@ func TestNewREST(t *testing.T) {
}
}
}
}
func
TestRESTUnsupported
(
t
*
testing
.
T
)
{
var
ctx
api
.
Context
mockRegistry
:=
MockRegistry
{
OnApplyBinding
:
func
(
b
*
api
.
Binding
)
error
{
return
nil
},
}
b
:=
NewREST
(
mockRegistry
)
if
_
,
err
:=
b
.
Delete
(
ctx
,
"binding id"
);
err
==
nil
{
t
.
Errorf
(
"unexpected non-error"
)
}
if
_
,
err
:=
b
.
Update
(
ctx
,
&
api
.
Binding
{
PodID
:
"foo"
,
Host
:
"new machine"
});
err
==
nil
{
t
.
Errorf
(
"unexpected non-error"
)
}
if
_
,
err
:=
b
.
Get
(
ctx
,
"binding id"
);
err
==
nil
{
t
.
Errorf
(
"unexpected non-error"
)
}
if
_
,
err
:=
b
.
List
(
ctx
,
labels
.
Set
{
"name"
:
"foo"
}
.
AsSelector
(),
labels
.
Everything
());
err
==
nil
{
t
.
Errorf
(
"unexpected non-error"
)
}
// Try sending wrong object just to get 100% coverage
if
_
,
err
:=
b
.
Create
(
ctx
,
&
api
.
Pod
{});
err
==
nil
{
t
.
Errorf
(
"unexpected non-error"
)
}
}
func
TestRESTPost
(
t
*
testing
.
T
)
{
func
TestRESTPost
(
t
*
testing
.
T
)
{
table
:=
[]
struct
{
table
:=
[]
struct
{
b
*
api
.
Binding
b
*
api
.
Binding
...
...
pkg/registry/controller/rest.go
View file @
6f430741
...
@@ -122,6 +122,10 @@ func (*REST) New() runtime.Object {
...
@@ -122,6 +122,10 @@ func (*REST) New() runtime.Object {
return
&
api
.
ReplicationController
{}
return
&
api
.
ReplicationController
{}
}
}
func
(
*
REST
)
NewList
()
runtime
.
Object
{
return
&
api
.
ReplicationControllerList
{}
}
// Update replaces a given ReplicationController instance with an existing
// Update replaces a given ReplicationController instance with an existing
// instance in storage.registry.
// instance in storage.registry.
func
(
rs
*
REST
)
Update
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
func
(
rs
*
REST
)
Update
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
...
...
pkg/registry/endpoint/rest.go
View file @
6f430741
...
@@ -96,12 +96,11 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
...
@@ -96,12 +96,11 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
}),
nil
}),
nil
}
}
// Delete satisfies the RESTStorage interface but is unimplemented.
func
(
rs
*
REST
)
Delete
(
ctx
api
.
Context
,
id
string
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
return
nil
,
errors
.
NewBadRequest
(
"Endpoints are read-only"
)
}
// New implements the RESTStorage interface.
// New implements the RESTStorage interface.
func
(
rs
REST
)
New
()
runtime
.
Object
{
func
(
rs
REST
)
New
()
runtime
.
Object
{
return
&
api
.
Endpoints
{}
return
&
api
.
Endpoints
{}
}
}
func
(
*
REST
)
NewList
()
runtime
.
Object
{
return
&
api
.
EndpointsList
{}
}
pkg/registry/endpoint/rest_test.go
View file @
6f430741
...
@@ -96,14 +96,3 @@ func TestEndpointsRegistryList(t *testing.T) {
...
@@ -96,14 +96,3 @@ func TestEndpointsRegistryList(t *testing.T) {
t
.
Errorf
(
"Unexpected resource version: %#v"
,
sl
)
t
.
Errorf
(
"Unexpected resource version: %#v"
,
sl
)
}
}
}
}
func
TestEndpointsRegistryDelete
(
t
*
testing
.
T
)
{
registry
:=
registrytest
.
NewServiceRegistry
()
storage
:=
NewREST
(
registry
)
_
,
err
:=
storage
.
Delete
(
api
.
NewContext
(),
"n/a"
)
if
err
==
nil
{
t
.
Error
(
"unexpected non-error"
)
}
else
if
!
errors
.
IsBadRequest
(
err
)
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
}
pkg/registry/event/rest.go
View file @
6f430741
...
@@ -128,7 +128,6 @@ func (*REST) New() runtime.Object {
...
@@ -128,7 +128,6 @@ func (*REST) New() runtime.Object {
return
&
api
.
Event
{}
return
&
api
.
Event
{}
}
}
// Update returns an error: Events are not mutable.
func
(
*
REST
)
NewList
()
runtime
.
Object
{
func
(
rs
*
REST
)
Update
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
return
&
api
.
EventList
{}
return
nil
,
fmt
.
Errorf
(
"not allowed: 'Event' objects are not mutable"
)
}
}
pkg/registry/event/rest_test.go
View file @
6f430741
...
@@ -172,20 +172,6 @@ func TestRESTgetAttrs(t *testing.T) {
...
@@ -172,20 +172,6 @@ func TestRESTgetAttrs(t *testing.T) {
}
}
}
}
func
TestRESTUpdate
(
t
*
testing
.
T
)
{
_
,
rest
:=
NewTestREST
()
eventA
:=
testEvent
(
"foo"
)
c
,
err
:=
rest
.
Create
(
api
.
NewDefaultContext
(),
eventA
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error %v"
,
err
)
}
<-
c
_
,
err
=
rest
.
Update
(
api
.
NewDefaultContext
(),
eventA
)
if
err
==
nil
{
t
.
Errorf
(
"unexpected non-error"
)
}
}
func
TestRESTList
(
t
*
testing
.
T
)
{
func
TestRESTList
(
t
*
testing
.
T
)
{
reg
,
rest
:=
NewTestREST
()
reg
,
rest
:=
NewTestREST
()
eventA
:=
&
api
.
Event
{
eventA
:=
&
api
.
Event
{
...
...
pkg/registry/minion/rest.go
View file @
6f430741
...
@@ -104,6 +104,10 @@ func (rs *REST) New() runtime.Object {
...
@@ -104,6 +104,10 @@ func (rs *REST) New() runtime.Object {
return
&
api
.
Node
{}
return
&
api
.
Node
{}
}
}
func
(
*
REST
)
NewList
()
runtime
.
Object
{
return
&
api
.
NodeList
{}
}
// Update satisfies the RESTStorage interface.
// Update satisfies the RESTStorage interface.
func
(
rs
*
REST
)
Update
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
func
(
rs
*
REST
)
Update
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
minion
,
ok
:=
obj
.
(
*
api
.
Node
)
minion
,
ok
:=
obj
.
(
*
api
.
Node
)
...
...
pkg/registry/pod/rest.go
View file @
6f430741
...
@@ -161,6 +161,10 @@ func (*REST) New() runtime.Object {
...
@@ -161,6 +161,10 @@ func (*REST) New() runtime.Object {
return
&
api
.
Pod
{}
return
&
api
.
Pod
{}
}
}
func
(
*
REST
)
NewList
()
runtime
.
Object
{
return
&
api
.
PodList
{}
}
func
(
rs
*
REST
)
Update
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
func
(
rs
*
REST
)
Update
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
pod
:=
obj
.
(
*
api
.
Pod
)
pod
:=
obj
.
(
*
api
.
Pod
)
if
!
api
.
ValidNamespace
(
ctx
,
&
pod
.
ObjectMeta
)
{
if
!
api
.
ValidNamespace
(
ctx
,
&
pod
.
ObjectMeta
)
{
...
...
pkg/registry/service/rest.go
View file @
6f430741
...
@@ -217,6 +217,10 @@ func (*REST) New() runtime.Object {
...
@@ -217,6 +217,10 @@ func (*REST) New() runtime.Object {
return
&
api
.
Service
{}
return
&
api
.
Service
{}
}
}
func
(
*
REST
)
NewList
()
runtime
.
Object
{
return
&
api
.
Service
{}
}
func
(
rs
*
REST
)
Update
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
func
(
rs
*
REST
)
Update
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
(
<-
chan
apiserver
.
RESTResult
,
error
)
{
service
:=
obj
.
(
*
api
.
Service
)
service
:=
obj
.
(
*
api
.
Service
)
if
!
api
.
ValidNamespace
(
ctx
,
&
service
.
ObjectMeta
)
{
if
!
api
.
ValidNamespace
(
ctx
,
&
service
.
ObjectMeta
)
{
...
...
test/integration/auth_test.go
View file @
6f430741
...
@@ -222,7 +222,7 @@ func getTestRequests() []struct {
...
@@ -222,7 +222,7 @@ func getTestRequests() []struct {
{
"PUT"
,
"/api/v1beta1/endpoints/a"
+
syncFlags
,
aEndpoints
,
code200
},
{
"PUT"
,
"/api/v1beta1/endpoints/a"
+
syncFlags
,
aEndpoints
,
code200
},
{
"GET"
,
"/api/v1beta1/endpoints"
,
""
,
code200
},
{
"GET"
,
"/api/v1beta1/endpoints"
,
""
,
code200
},
{
"GET"
,
"/api/v1beta1/endpoints/a"
,
""
,
code200
},
{
"GET"
,
"/api/v1beta1/endpoints/a"
,
""
,
code200
},
{
"DELETE"
,
"/api/v1beta1/endpoints/a"
+
syncFlags
,
""
,
code40
0
},
{
"DELETE"
,
"/api/v1beta1/endpoints/a"
+
syncFlags
,
""
,
code40
5
},
// Normal methods on minions
// Normal methods on minions
{
"GET"
,
"/api/v1beta1/minions"
,
""
,
code200
},
{
"GET"
,
"/api/v1beta1/minions"
,
""
,
code200
},
...
@@ -235,7 +235,7 @@ func getTestRequests() []struct {
...
@@ -235,7 +235,7 @@ func getTestRequests() []struct {
// Normal methods on events
// Normal methods on events
{
"GET"
,
"/api/v1beta1/events"
,
""
,
code200
},
{
"GET"
,
"/api/v1beta1/events"
,
""
,
code200
},
{
"POST"
,
"/api/v1beta1/events"
+
syncFlags
,
aEvent
,
code200
},
{
"POST"
,
"/api/v1beta1/events"
+
syncFlags
,
aEvent
,
code200
},
{
"PUT"
,
"/api/v1beta1/events/a"
+
syncFlags
,
aEvent
,
code
500
},
// See #2114 about why 500
{
"PUT"
,
"/api/v1beta1/events/a"
+
syncFlags
,
aEvent
,
code
405
},
{
"GET"
,
"/api/v1beta1/events"
,
""
,
code200
},
{
"GET"
,
"/api/v1beta1/events"
,
""
,
code200
},
{
"GET"
,
"/api/v1beta1/events"
,
""
,
code200
},
{
"GET"
,
"/api/v1beta1/events"
,
""
,
code200
},
{
"GET"
,
"/api/v1beta1/events/a"
,
""
,
code200
},
{
"GET"
,
"/api/v1beta1/events/a"
,
""
,
code200
},
...
@@ -245,10 +245,10 @@ func getTestRequests() []struct {
...
@@ -245,10 +245,10 @@ func getTestRequests() []struct {
{
"GET"
,
"/api/v1beta1/bindings"
,
""
,
code405
},
// Bindings are write-only
{
"GET"
,
"/api/v1beta1/bindings"
,
""
,
code405
},
// Bindings are write-only
{
"POST"
,
"/api/v1beta1/pods"
+
syncFlags
,
aPod
,
code200
},
// Need a pod to bind or you get a 404
{
"POST"
,
"/api/v1beta1/pods"
+
syncFlags
,
aPod
,
code200
},
// Need a pod to bind or you get a 404
{
"POST"
,
"/api/v1beta1/bindings"
+
syncFlags
,
aBinding
,
code200
},
{
"POST"
,
"/api/v1beta1/bindings"
+
syncFlags
,
aBinding
,
code200
},
{
"PUT"
,
"/api/v1beta1/bindings/a"
+
syncFlags
,
aBinding
,
code
500
},
// See #2114 about why 500
{
"PUT"
,
"/api/v1beta1/bindings/a"
+
syncFlags
,
aBinding
,
code
405
},
{
"GET"
,
"/api/v1beta1/bindings"
,
""
,
code405
},
{
"GET"
,
"/api/v1beta1/bindings"
,
""
,
code405
},
{
"GET"
,
"/api/v1beta1/bindings/a"
,
""
,
code40
4
},
// No bindings instances
{
"GET"
,
"/api/v1beta1/bindings/a"
,
""
,
code40
5
},
// No bindings instances
{
"DELETE"
,
"/api/v1beta1/bindings/a"
+
syncFlags
,
""
,
code40
4
},
{
"DELETE"
,
"/api/v1beta1/bindings/a"
+
syncFlags
,
""
,
code40
5
},
// Non-existent object type.
// Non-existent object type.
{
"GET"
,
"/api/v1beta1/foo"
,
""
,
code404
},
{
"GET"
,
"/api/v1beta1/foo"
,
""
,
code404
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment