mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 08:17:26 +00:00
Split operations code and add comments
This commit is contained in:
parent
9069696514
commit
fe7f611d88
@ -79,35 +79,32 @@ func New(storage map[string]RESTStorage, prefix string) *APIServer {
|
|||||||
mux: http.NewServeMux(),
|
mux: http.NewServeMux(),
|
||||||
}
|
}
|
||||||
|
|
||||||
s.mux.Handle("/logs/", http.StripPrefix("/logs/", http.FileServer(http.Dir("/var/log/"))))
|
// Primary API methods
|
||||||
s.mux.HandleFunc(s.prefix+"/", s.handleREST)
|
s.mux.HandleFunc(s.prefix+"/", s.handleREST)
|
||||||
healthz.InstallHandler(s.mux)
|
s.mux.HandleFunc(s.watchPrefix()+"/", s.handleWatch)
|
||||||
|
|
||||||
s.mux.HandleFunc("/version", s.handleVersionReq)
|
// Support services for the apiserver
|
||||||
|
s.mux.Handle("/logs/", http.StripPrefix("/logs/", http.FileServer(http.Dir("/var/log/"))))
|
||||||
|
healthz.InstallHandler(s.mux)
|
||||||
|
s.mux.HandleFunc("/version", handleVersion)
|
||||||
s.mux.HandleFunc("/", handleIndex)
|
s.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.handleOperationRequest)
|
s.mux.HandleFunc(s.operationPrefix(), s.handleOperationRequest)
|
||||||
s.mux.HandleFunc(s.operationPrefix()+"/", s.handleOperationRequest)
|
s.mux.HandleFunc(s.operationPrefix()+"/", s.handleOperationRequest)
|
||||||
|
|
||||||
s.mux.HandleFunc(s.watchPrefix()+"/", s.handleWatch)
|
// Proxy minion requests
|
||||||
|
|
||||||
s.mux.HandleFunc("/proxy/minion/", s.handleProxyMinion)
|
s.mux.HandleFunc("/proxy/minion/", s.handleProxyMinion)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleVersionReq writes the server's version information.
|
// ServeHTTP implements the standard net/http interface.
|
||||||
func (s *APIServer) handleVersionReq(w http.ResponseWriter, req *http.Request) {
|
|
||||||
writeRawJSON(http.StatusOK, version.Get(), w)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTP Handler interface
|
|
||||||
func (s *APIServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (s *APIServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if x := recover(); x != nil {
|
if x := recover(); x != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
fmt.Fprint(w, "apiserver panic. Look in log for details.")
|
fmt.Fprint(w, "apis panic. Look in log for details.")
|
||||||
glog.Infof("APIServer panic'd on %v %v: %#v\n%s\n", req.Method, req.RequestURI, x, debug.Stack())
|
glog.Infof("APIServer panic'd on %v %v: %#v\n%s\n", req.Method, req.RequestURI, x, debug.Stack())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -145,33 +142,6 @@ func (s *APIServer) handleREST(w http.ResponseWriter, req *http.Request) {
|
|||||||
s.handleRESTStorage(requestParts, req, w, storage)
|
s.handleRESTStorage(requestParts, req, w, storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// finishReq finishes up a request, waiting until the operation finishes or, after a timeout, creating an
|
|
||||||
// Operation to receive the result and returning its ID down the writer.
|
|
||||||
func (s *APIServer) finishReq(out <-chan interface{}, sync bool, timeout time.Duration, w http.ResponseWriter) {
|
|
||||||
op := s.ops.NewOperation(out)
|
|
||||||
if sync {
|
|
||||||
op.WaitFor(timeout)
|
|
||||||
}
|
|
||||||
obj, complete := op.StatusOrResult()
|
|
||||||
if complete {
|
|
||||||
status := http.StatusOK
|
|
||||||
switch stat := obj.(type) {
|
|
||||||
case api.Status:
|
|
||||||
httplog.LogOf(w).Addf("programmer error: use *api.Status as a result, not api.Status.")
|
|
||||||
if stat.Code != 0 {
|
|
||||||
status = stat.Code
|
|
||||||
}
|
|
||||||
case *api.Status:
|
|
||||||
if stat.Code != 0 {
|
|
||||||
status = stat.Code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writeJSON(status, obj, w)
|
|
||||||
} else {
|
|
||||||
writeJSON(http.StatusAccepted, obj, w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
||||||
// on path length, according to the following table:
|
// on path length, according to the following table:
|
||||||
// Method Path Action
|
// Method Path Action
|
||||||
@ -217,6 +187,7 @@ func (s *APIServer) handleRESTStorage(parts []string, req *http.Request, w http.
|
|||||||
default:
|
default:
|
||||||
notFound(w, req)
|
notFound(w, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
case "POST":
|
case "POST":
|
||||||
if len(parts) != 1 {
|
if len(parts) != 1 {
|
||||||
notFound(w, req)
|
notFound(w, req)
|
||||||
@ -245,7 +216,9 @@ func (s *APIServer) handleRESTStorage(parts []string, req *http.Request, w http.
|
|||||||
internalError(err, w)
|
internalError(err, w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.finishReq(out, sync, timeout, w)
|
op := s.createOperation(out, sync, timeout)
|
||||||
|
s.finishReq(op, w)
|
||||||
|
|
||||||
case "DELETE":
|
case "DELETE":
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
notFound(w, req)
|
notFound(w, req)
|
||||||
@ -260,7 +233,9 @@ func (s *APIServer) handleRESTStorage(parts []string, req *http.Request, w http.
|
|||||||
internalError(err, w)
|
internalError(err, w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.finishReq(out, sync, timeout, w)
|
op := s.createOperation(out, sync, timeout)
|
||||||
|
s.finishReq(op, w)
|
||||||
|
|
||||||
case "PUT":
|
case "PUT":
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
notFound(w, req)
|
notFound(w, req)
|
||||||
@ -289,12 +264,51 @@ func (s *APIServer) handleRESTStorage(parts []string, req *http.Request, w http.
|
|||||||
internalError(err, w)
|
internalError(err, w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.finishReq(out, sync, timeout, w)
|
op := s.createOperation(out, sync, timeout)
|
||||||
|
s.finishReq(op, w)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
notFound(w, req)
|
notFound(w, req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleVersionReq writes the server's version information.
|
||||||
|
func handleVersion(w http.ResponseWriter, req *http.Request) {
|
||||||
|
writeRawJSON(http.StatusOK, version.Get(), w)
|
||||||
|
}
|
||||||
|
|
||||||
|
// createOperation creates an operation to process a channel response
|
||||||
|
func (s *APIServer) createOperation(out <-chan interface{}, sync bool, timeout time.Duration) *Operation {
|
||||||
|
op := s.ops.NewOperation(out)
|
||||||
|
if sync {
|
||||||
|
op.WaitFor(timeout)
|
||||||
|
}
|
||||||
|
return op
|
||||||
|
}
|
||||||
|
|
||||||
|
// finishReq finishes up a request, waiting until the operation finishes or, after a timeout, creating an
|
||||||
|
// Operation to receive the result and returning its ID down the writer.
|
||||||
|
func (s *APIServer) finishReq(op *Operation, w http.ResponseWriter) {
|
||||||
|
obj, complete := op.StatusOrResult()
|
||||||
|
if complete {
|
||||||
|
status := http.StatusOK
|
||||||
|
switch stat := obj.(type) {
|
||||||
|
case api.Status:
|
||||||
|
httplog.LogOf(w).Addf("programmer error: use *api.Status as a result, not api.Status.")
|
||||||
|
if stat.Code != 0 {
|
||||||
|
status = stat.Code
|
||||||
|
}
|
||||||
|
case *api.Status:
|
||||||
|
if stat.Code != 0 {
|
||||||
|
status = stat.Code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeJSON(status, obj, w)
|
||||||
|
} else {
|
||||||
|
writeJSON(http.StatusAccepted, obj, w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *APIServer) operationPrefix() string {
|
func (s *APIServer) operationPrefix() string {
|
||||||
return path.Join(s.prefix, "operations")
|
return path.Join(s.prefix, "operations")
|
||||||
}
|
}
|
||||||
@ -340,6 +354,7 @@ func (s *APIServer) watchPrefix() string {
|
|||||||
return path.Join(s.prefix, "watch")
|
return path.Join(s.prefix, "watch")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleWatch processes a watch request
|
||||||
func (s *APIServer) handleWatch(w http.ResponseWriter, req *http.Request) {
|
func (s *APIServer) handleWatch(w http.ResponseWriter, req *http.Request) {
|
||||||
prefix := s.watchPrefix()
|
prefix := s.watchPrefix()
|
||||||
if !strings.HasPrefix(req.URL.Path, prefix) {
|
if !strings.HasPrefix(req.URL.Path, prefix) {
|
||||||
@ -381,6 +396,7 @@ func (s *APIServer) handleWatch(w http.ResponseWriter, req *http.Request) {
|
|||||||
notFound(w, req)
|
notFound(w, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeJSON renders an object as JSON to the response
|
||||||
func writeJSON(statusCode int, object interface{}, w http.ResponseWriter) {
|
func writeJSON(statusCode int, object interface{}, w http.ResponseWriter) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(statusCode)
|
w.WriteHeader(statusCode)
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// internalError renders a generic error to the response
|
||||||
func internalError(err error, w http.ResponseWriter) {
|
func internalError(err error, w http.ResponseWriter) {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
fmt.Fprintf(w, "Internal Error: %#v", err)
|
fmt.Fprintf(w, "Internal Error: %#v", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user