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
22c99c98
Commit
22c99c98
authored
Jan 12, 2015
by
Clayton Coleman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Split RESTStorage into separate interfaces
Omit unimplemented interfaces from Swagger
parent
a52b2163
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
235 additions
and
88 deletions
+235
-88
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/controller/rest.go
+4
-0
rest.go
pkg/registry/endpoint/rest.go
+4
-0
rest.go
pkg/registry/event/rest.go
+4
-0
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
No files found.
pkg/apiserver/apiserver.go
View file @
22c99c98
...
@@ -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 @
22c99c98
...
@@ -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 @
22c99c98
...
@@ -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 @
22c99c98
...
@@ -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 @
22c99c98
...
@@ -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 @
22c99c98
...
@@ -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 @
22c99c98
...
@@ -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 @
22c99c98
...
@@ -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 @
22c99c98
...
@@ -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/controller/rest.go
View file @
22c99c98
...
@@ -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 @
22c99c98
...
@@ -105,3 +105,7 @@ func (rs *REST) Delete(ctx api.Context, id string) (<-chan apiserver.RESTResult,
...
@@ -105,3 +105,7 @@ func (rs *REST) Delete(ctx api.Context, id string) (<-chan apiserver.RESTResult,
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/event/rest.go
View file @
22c99c98
...
@@ -128,6 +128,10 @@ func (*REST) New() runtime.Object {
...
@@ -128,6 +128,10 @@ func (*REST) New() runtime.Object {
return
&
api
.
Event
{}
return
&
api
.
Event
{}
}
}
func
(
*
REST
)
NewList
()
runtime
.
Object
{
return
&
api
.
EventList
{}
}
// Update returns an error: Events are not mutable.
// Update returns an error: Events are not mutable.
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
)
{
return
nil
,
fmt
.
Errorf
(
"not allowed: 'Event' objects are not mutable"
)
return
nil
,
fmt
.
Errorf
(
"not allowed: 'Event' objects are not mutable"
)
...
...
pkg/registry/minion/rest.go
View file @
22c99c98
...
@@ -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 @
22c99c98
...
@@ -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 @
22c99c98
...
@@ -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
)
{
...
...
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