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
a74fac7d
Commit
a74fac7d
authored
Aug 06, 2014
by
Clayton Coleman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Centralize path magic in apiserver into the New method
Make OperationHandler and WatchHandler properly encapsulate their concerns and make them not depend on the global path
parent
2297bf8c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
59 additions
and
63 deletions
+59
-63
apiserver.go
pkg/apiserver/apiserver.go
+42
-25
operation.go
pkg/apiserver/operation.go
+11
-25
watch.go
pkg/apiserver/watch.go
+6
-13
No files found.
pkg/apiserver/apiserver.go
View file @
a74fac7d
...
@@ -21,6 +21,7 @@ import (
...
@@ -21,6 +21,7 @@ import (
"fmt"
"fmt"
"io/ioutil"
"io/ioutil"
"net/http"
"net/http"
"path"
"runtime/debug"
"runtime/debug"
"strings"
"strings"
"time"
"time"
...
@@ -48,12 +49,11 @@ type Codec interface {
...
@@ -48,12 +49,11 @@ type Codec interface {
//
//
// TODO: consider migrating this to go-restful which is a more full-featured version of the same thing.
// TODO: consider migrating this to go-restful which is a more full-featured version of the same thing.
type
APIServer
struct
{
type
APIServer
struct
{
prefix
string
storage
map
[
string
]
RESTStorage
storage
map
[
string
]
RESTStorage
codec
Codec
codec
Codec
ops
*
Operations
ops
*
Operations
mux
*
http
.
ServeMux
asyncOpWait
time
.
Duration
asyncOpWait
time
.
Duration
handler
http
.
Handler
}
}
// New creates a new APIServer object. 'storage' contains a map of handlers. 'codec'
// New creates a new APIServer object. 'storage' contains a map of handlers. 'codec'
...
@@ -65,31 +65,43 @@ type APIServer struct {
...
@@ -65,31 +65,43 @@ type APIServer struct {
// TODO: add multitype codec serialization
// TODO: add multitype codec serialization
func
New
(
storage
map
[
string
]
RESTStorage
,
codec
Codec
,
prefix
string
)
*
APIServer
{
func
New
(
storage
map
[
string
]
RESTStorage
,
codec
Codec
,
prefix
string
)
*
APIServer
{
s
:=
&
APIServer
{
s
:=
&
APIServer
{
prefix
:
strings
.
TrimRight
(
prefix
,
"/"
),
storage
:
storage
,
storage
:
storage
,
codec
:
codec
,
codec
:
codec
,
ops
:
NewOperations
(),
ops
:
NewOperations
(),
mux
:
http
.
NewServeMux
(),
// Delay just long enough to handle most simple write operations
// Delay just long enough to handle most simple write operations
asyncOpWait
:
time
.
Millisecond
*
25
,
asyncOpWait
:
time
.
Millisecond
*
25
,
}
}
// Primary API methods
mux
:=
http
.
NewServeMux
()
s
.
mux
.
HandleFunc
(
s
.
prefix
+
"/"
,
s
.
handleREST
)
s
.
mux
.
HandleFunc
(
s
.
watchPrefix
()
+
"/"
,
s
.
handleWatch
)
prefix
=
strings
.
TrimRight
(
prefix
,
"/"
)
// Primary API handlers
restPrefix
:=
prefix
+
"/"
mux
.
Handle
(
restPrefix
,
http
.
StripPrefix
(
restPrefix
,
http
.
HandlerFunc
(
s
.
handleREST
)))
// Watch API handlers
watchPrefix
:=
path
.
Join
(
prefix
,
"watch"
)
+
"/"
mux
.
Handle
(
watchPrefix
,
http
.
StripPrefix
(
watchPrefix
,
&
WatchHandler
{
storage
}))
// Support services for the apiserver
// Support services for the apiserver
s
.
mux
.
Handle
(
"/logs/"
,
http
.
StripPrefix
(
"/logs/"
,
http
.
FileServer
(
http
.
Dir
(
"/var/log/"
))))
logsPrefix
:=
"/logs/"
healthz
.
InstallHandler
(
s
.
mux
)
mux
.
Handle
(
logsPrefix
,
http
.
StripPrefix
(
logsPrefix
,
http
.
FileServer
(
http
.
Dir
(
"/var/log/"
))))
s
.
mux
.
HandleFunc
(
"/version"
,
handleVersion
)
healthz
.
InstallHandler
(
mux
)
s
.
mux
.
HandleFunc
(
"/"
,
handleIndex
)
mux
.
HandleFunc
(
"/version"
,
handleVersion
)
mux
.
HandleFunc
(
"/"
,
handleIndex
)
// Handle both operations and operations/* with the same handler
// Handle both operations and operations/* with the same handler
s
.
mux
.
HandleFunc
(
s
.
operationPrefix
(),
s
.
handleOperation
)
handler
:=
&
OperationHandler
{
s
.
ops
,
s
.
codec
}
s
.
mux
.
HandleFunc
(
s
.
operationPrefix
()
+
"/"
,
s
.
handleOperation
)
operationPrefix
:=
path
.
Join
(
prefix
,
"operations"
)
mux
.
Handle
(
operationPrefix
,
http
.
StripPrefix
(
operationPrefix
,
handler
))
operationsPrefix
:=
operationPrefix
+
"/"
mux
.
Handle
(
operationsPrefix
,
http
.
StripPrefix
(
operationsPrefix
,
handler
))
// Proxy minion requests
// Proxy minion requests
s
.
mux
.
Handle
(
"/proxy/minion/"
,
http
.
StripPrefix
(
"/proxy/minion"
,
http
.
HandlerFunc
(
handleProxyMinion
)))
mux
.
Handle
(
"/proxy/minion/"
,
http
.
StripPrefix
(
"/proxy/minion"
,
http
.
HandlerFunc
(
handleProxyMinion
)))
s
.
handler
=
mux
return
s
return
s
}
}
...
@@ -112,29 +124,25 @@ func (s *APIServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
...
@@ -112,29 +124,25 @@ func (s *APIServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
),
),
)
.
Log
()
)
.
Log
()
// Dispatch
via our mux.
// Dispatch
to the internal handler
s
.
mux
.
ServeHTTP
(
w
,
req
)
s
.
handler
.
ServeHTTP
(
w
,
req
)
}
}
// handleREST handles requests to all our RESTStorage objects.
// handleREST handles requests to all our RESTStorage objects.
func
(
s
*
APIServer
)
handleREST
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
func
(
s
*
APIServer
)
handleREST
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
if
!
strings
.
HasPrefix
(
req
.
URL
.
Path
,
s
.
prefix
)
{
parts
:=
splitPath
(
req
.
URL
.
Path
)
notFound
(
w
,
req
)
if
len
(
parts
)
<
1
{
return
}
requestParts
:=
strings
.
Split
(
req
.
URL
.
Path
[
len
(
s
.
prefix
)
:
],
"/"
)[
1
:
]
if
len
(
requestParts
)
<
1
{
notFound
(
w
,
req
)
notFound
(
w
,
req
)
return
return
}
}
storage
:=
s
.
storage
[
requestP
arts
[
0
]]
storage
:=
s
.
storage
[
p
arts
[
0
]]
if
storage
==
nil
{
if
storage
==
nil
{
httplog
.
LogOf
(
w
)
.
Addf
(
"'%v' has no storage object"
,
requestP
arts
[
0
])
httplog
.
LogOf
(
w
)
.
Addf
(
"'%v' has no storage object"
,
p
arts
[
0
])
notFound
(
w
,
req
)
notFound
(
w
,
req
)
return
return
}
}
s
.
handleRESTStorage
(
requestP
arts
,
req
,
w
,
storage
)
s
.
handleRESTStorage
(
p
arts
,
req
,
w
,
storage
)
}
}
// handleRESTStorage is the main dispatcher for a storage object. It switches on the HTTP method, and then
// handleRESTStorage is the main dispatcher for a storage object. It switches on the HTTP method, and then
...
@@ -347,3 +355,12 @@ func readBody(req *http.Request) ([]byte, error) {
...
@@ -347,3 +355,12 @@ func readBody(req *http.Request) ([]byte, error) {
defer
req
.
Body
.
Close
()
defer
req
.
Body
.
Close
()
return
ioutil
.
ReadAll
(
req
.
Body
)
return
ioutil
.
ReadAll
(
req
.
Body
)
}
}
// splitPath returns the segments for a URL path
func
splitPath
(
path
string
)
[]
string
{
path
=
strings
.
Trim
(
path
,
"/"
)
if
path
==
""
{
return
[]
string
{}
}
return
strings
.
Split
(
path
,
"/"
)
}
pkg/apiserver/operation.go
View file @
a74fac7d
...
@@ -18,10 +18,8 @@ package apiserver
...
@@ -18,10 +18,8 @@ package apiserver
import
(
import
(
"net/http"
"net/http"
"path"
"sort"
"sort"
"strconv"
"strconv"
"strings"
"sync"
"sync"
"sync/atomic"
"sync/atomic"
"time"
"time"
...
@@ -30,37 +28,25 @@ import (
...
@@ -30,37 +28,25 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
)
)
func
(
s
*
APIServer
)
operationPrefix
()
string
{
type
OperationHandler
struct
{
return
path
.
Join
(
s
.
prefix
,
"operations"
)
ops
*
Operations
codec
Codec
}
}
func
(
s
*
APIServer
)
handleOperation
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
func
(
h
*
OperationHandler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
opPrefix
:=
s
.
operationPrefix
()
parts
:=
splitPath
(
req
.
URL
.
Path
)
if
!
strings
.
HasPrefix
(
req
.
URL
.
Path
,
opPrefix
)
{
if
len
(
parts
)
>
1
||
req
.
Method
!=
"GET"
{
notFound
(
w
,
req
)
return
}
trimmed
:=
strings
.
TrimLeft
(
req
.
URL
.
Path
[
len
(
opPrefix
)
:
],
"/"
)
parts
:=
strings
.
Split
(
trimmed
,
"/"
)
if
trimmed
==
""
{
parts
=
[]
string
{}
}
if
len
(
parts
)
>
1
{
notFound
(
w
,
req
)
return
}
if
req
.
Method
!=
"GET"
{
notFound
(
w
,
req
)
notFound
(
w
,
req
)
return
return
}
}
if
len
(
parts
)
==
0
{
if
len
(
parts
)
==
0
{
// List outstanding operations.
// List outstanding operations.
list
:=
s
.
ops
.
List
()
list
:=
h
.
ops
.
List
()
writeJSON
(
http
.
StatusOK
,
s
.
codec
,
list
,
w
)
writeJSON
(
http
.
StatusOK
,
h
.
codec
,
list
,
w
)
return
return
}
}
op
:=
s
.
ops
.
Get
(
parts
[
0
])
op
:=
h
.
ops
.
Get
(
parts
[
0
])
if
op
==
nil
{
if
op
==
nil
{
notFound
(
w
,
req
)
notFound
(
w
,
req
)
return
return
...
@@ -68,9 +54,9 @@ func (s *APIServer) handleOperation(w http.ResponseWriter, req *http.Request) {
...
@@ -68,9 +54,9 @@ func (s *APIServer) handleOperation(w http.ResponseWriter, req *http.Request) {
obj
,
complete
:=
op
.
StatusOrResult
()
obj
,
complete
:=
op
.
StatusOrResult
()
if
complete
{
if
complete
{
writeJSON
(
http
.
StatusOK
,
s
.
codec
,
obj
,
w
)
writeJSON
(
http
.
StatusOK
,
h
.
codec
,
obj
,
w
)
}
else
{
}
else
{
writeJSON
(
http
.
StatusAccepted
,
s
.
codec
,
obj
,
w
)
writeJSON
(
http
.
StatusAccepted
,
h
.
codec
,
obj
,
w
)
}
}
}
}
...
...
pkg/apiserver/watch.go
View file @
a74fac7d
...
@@ -19,8 +19,6 @@ package apiserver
...
@@ -19,8 +19,6 @@ package apiserver
import
(
import
(
"encoding/json"
"encoding/json"
"net/http"
"net/http"
"path"
"strings"
"code.google.com/p/go.net/websocket"
"code.google.com/p/go.net/websocket"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
...
@@ -28,22 +26,17 @@ import (
...
@@ -28,22 +26,17 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
)
func
(
s
*
APIServer
)
watchPrefix
()
string
{
type
WatchHandler
struct
{
return
path
.
Join
(
s
.
prefix
,
"watch"
)
storage
map
[
string
]
RESTStorage
}
}
// handleWatch processes a watch request
// handleWatch processes a watch request
func
(
s
*
APIServer
)
handleWatch
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
func
(
h
*
WatchHandler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
prefix
:=
s
.
watchPrefix
()
parts
:=
splitPath
(
req
.
URL
.
Path
)
if
!
strings
.
HasPrefix
(
req
.
URL
.
Path
,
prefix
)
{
if
len
(
parts
)
<
1
||
req
.
Method
!=
"GET"
{
notFound
(
w
,
req
)
return
}
parts
:=
strings
.
Split
(
req
.
URL
.
Path
[
len
(
prefix
)
:
],
"/"
)[
1
:
]
if
req
.
Method
!=
"GET"
||
len
(
parts
)
<
1
{
notFound
(
w
,
req
)
notFound
(
w
,
req
)
}
}
storage
:=
s
.
storage
[
parts
[
0
]]
storage
:=
h
.
storage
[
parts
[
0
]]
if
storage
==
nil
{
if
storage
==
nil
{
notFound
(
w
,
req
)
notFound
(
w
,
req
)
}
}
...
...
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