Remove intermediate API server objects
Instead just generate HTTP handler functions directly.
This commit is contained in:
@@ -34,9 +34,11 @@ func NotFound(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, "404 request not found", http.StatusNotFound)
|
http.Error(w, "404 request not found", http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubeletServer implements HTTP endpoints for serving kubelet API's
|
// NotImplemented provides a handler for cases where a provider does not implement a given API
|
||||||
type KubeletServer struct {
|
func NotImplemented(w http.ResponseWriter, r *http.Request) {
|
||||||
p Provider
|
logger := log.G(loggingContext(r))
|
||||||
|
log.Trace(logger, "501 not implemented")
|
||||||
|
http.Error(w, "501 not implemented", http.StatusNotImplemented)
|
||||||
}
|
}
|
||||||
|
|
||||||
// KubeletServertStart starts the virtual kubelet HTTP server.
|
// KubeletServertStart starts the virtual kubelet HTTP server.
|
||||||
@@ -47,9 +49,8 @@ func KubeletServerStart(p Provider) {
|
|||||||
addr := fmt.Sprintf(":%s", port)
|
addr := fmt.Sprintf(":%s", port)
|
||||||
|
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
s := &KubeletServer{p: p}
|
r.HandleFunc("/containerLogs/{namespace}/{pod}/{container}", PodLogsHandlerFunc(p)).Methods("GET")
|
||||||
r.HandleFunc("/containerLogs/{namespace}/{pod}/{container}", s.ApiServerHandler).Methods("GET")
|
r.HandleFunc("/exec/{namespace}/{pod}/{container}", PodExecHandlerFunc(p)).Methods("POST")
|
||||||
r.HandleFunc("/exec/{namespace}/{pod}/{container}", s.ApiServerHandlerExec).Methods("POST")
|
|
||||||
r.NotFoundHandler = http.HandlerFunc(NotFound)
|
r.NotFoundHandler = http.HandlerFunc(NotFound)
|
||||||
|
|
||||||
if err := http.ListenAndServeTLS(addr, certFilePath, keyFilePath, r); err != nil {
|
if err := http.ListenAndServeTLS(addr, certFilePath, keyFilePath, r); err != nil {
|
||||||
@@ -61,31 +62,26 @@ func KubeletServerStart(p Provider) {
|
|||||||
// TLS is never enabled on this endpoint.
|
// TLS is never enabled on this endpoint.
|
||||||
func MetricsServerStart(p Provider, addr string) {
|
func MetricsServerStart(p Provider, addr string) {
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
s := &MetricsServer{p: p}
|
|
||||||
r.HandleFunc("/stats/summary", s.MetricsSummaryHandler).Methods("GET")
|
mp, ok := p.(MetricsProvider)
|
||||||
r.HandleFunc("/stats/summary/", s.MetricsSummaryHandler).Methods("GET")
|
if !ok {
|
||||||
|
r.HandleFunc("/stats/summary", NotImplemented).Methods("GET")
|
||||||
|
r.HandleFunc("/stats/summary/", NotImplemented).Methods("GET")
|
||||||
|
} else {
|
||||||
|
r.HandleFunc("/stats/summary", PodMetricsHandlerFunc(mp)).Methods("GET")
|
||||||
|
r.HandleFunc("/stats/summary/", PodMetricsHandlerFunc(mp)).Methods("GET")
|
||||||
|
}
|
||||||
r.NotFoundHandler = http.HandlerFunc(NotFound)
|
r.NotFoundHandler = http.HandlerFunc(NotFound)
|
||||||
if err := http.ListenAndServe(addr, r); err != nil {
|
if err := http.ListenAndServe(addr, r); err != nil {
|
||||||
log.G(context.TODO()).WithError(err).Error("Error starting http server")
|
log.G(context.TODO()).WithError(err).Error("Error starting http server")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MetricsServer provides an HTTP endpopint for accessing pod metrics
|
// PodMetricsHandlerFunc makes an HTTP handler for implementing the kubelet summary stats endpoint
|
||||||
type MetricsServer struct {
|
func PodMetricsHandlerFunc(mp MetricsProvider) http.HandlerFunc {
|
||||||
p Provider
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
|
||||||
|
|
||||||
// MetricsSummaryHandler is an HTTP handler for implementing the kubelet summary stats endpoint
|
|
||||||
func (s *MetricsServer) MetricsSummaryHandler(w http.ResponseWriter, req *http.Request) {
|
|
||||||
ctx := loggingContext(req)
|
ctx := loggingContext(req)
|
||||||
|
|
||||||
mp, ok := s.p.(MetricsProvider)
|
|
||||||
if !ok {
|
|
||||||
log.G(ctx).Debug("stats not implemented for provider")
|
|
||||||
http.Error(w, "not implememnted", http.StatusNotImplemented)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
stats, err := mp.GetStatsSummary(req.Context())
|
stats, err := mp.GetStatsSummary(req.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Cause(err) == context.Canceled {
|
if errors.Cause(err) == context.Canceled {
|
||||||
@@ -107,8 +103,11 @@ func (s *MetricsServer) MetricsSummaryHandler(w http.ResponseWriter, req *http.R
|
|||||||
log.G(ctx).WithError(err).Debug("Could not write to client")
|
log.G(ctx).WithError(err).Debug("Could not write to client")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *KubeletServer) ApiServerHandler(w http.ResponseWriter, req *http.Request) {
|
// PodLogsHandlerFunc creates an http handler function from a provider to serve logs from a pod
|
||||||
|
func PodLogsHandlerFunc(p Provider) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
vars := mux.Vars(req)
|
vars := mux.Vars(req)
|
||||||
if len(vars) != 3 {
|
if len(vars) != 3 {
|
||||||
NotFound(w, req)
|
NotFound(w, req)
|
||||||
@@ -134,7 +133,7 @@ func (s *KubeletServer) ApiServerHandler(w http.ResponseWriter, req *http.Reques
|
|||||||
tail = t
|
tail = t
|
||||||
}
|
}
|
||||||
|
|
||||||
podsLogs, err := s.p.GetContainerLogs(ctx, namespace, pod, container, tail)
|
podsLogs, err := p.GetContainerLogs(ctx, namespace, pod, container, tail)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.G(ctx).WithError(err).Error("error getting container logs")
|
log.G(ctx).WithError(err).Error("error getting container logs")
|
||||||
http.Error(w, fmt.Sprintf("error while getting container logs: %v", err), http.StatusInternalServerError)
|
http.Error(w, fmt.Sprintf("error while getting container logs: %v", err), http.StatusInternalServerError)
|
||||||
@@ -145,8 +144,11 @@ func (s *KubeletServer) ApiServerHandler(w http.ResponseWriter, req *http.Reques
|
|||||||
log.G(ctx).WithError(err).Warn("error writing response to client")
|
log.G(ctx).WithError(err).Warn("error writing response to client")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *KubeletServer) ApiServerHandlerExec(w http.ResponseWriter, req *http.Request) {
|
// PodExecHandlerFunc makes an http handler func from a Provider which execs a command in a pod's container
|
||||||
|
func PodExecHandlerFunc(p Provider) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, req *http.Request) {
|
||||||
vars := mux.Vars(req)
|
vars := mux.Vars(req)
|
||||||
|
|
||||||
namespace := vars["namespace"]
|
namespace := vars["namespace"]
|
||||||
@@ -158,13 +160,6 @@ func (s *KubeletServer) ApiServerHandlerExec(w http.ResponseWriter, req *http.Re
|
|||||||
q := req.URL.Query()
|
q := req.URL.Query()
|
||||||
command := q["command"]
|
command := q["command"]
|
||||||
|
|
||||||
// streamOpts := &remotecommand.Options{
|
|
||||||
// Stdin: (q.Get("input") == "1"),
|
|
||||||
// Stdout: (q.Get("output") == "1"),
|
|
||||||
// Stderr: (q.Get("error") == "1"),
|
|
||||||
// TTY: (q.Get("tty") == "1"),
|
|
||||||
// }
|
|
||||||
|
|
||||||
// TODO: tty flag causes remotecommand.createStreams to wait for the wrong number of streams
|
// TODO: tty flag causes remotecommand.createStreams to wait for the wrong number of streams
|
||||||
streamOpts := &remotecommand.Options{
|
streamOpts := &remotecommand.Options{
|
||||||
Stdin: true,
|
Stdin: true,
|
||||||
@@ -176,5 +171,6 @@ func (s *KubeletServer) ApiServerHandlerExec(w http.ResponseWriter, req *http.Re
|
|||||||
idleTimeout := time.Second * 30
|
idleTimeout := time.Second * 30
|
||||||
streamCreationTimeout := time.Second * 30
|
streamCreationTimeout := time.Second * 30
|
||||||
|
|
||||||
remotecommand.ServeExec(w, req, s.p, fmt.Sprintf("%s-%s", namespace, pod), "", container, command, streamOpts, idleTimeout, streamCreationTimeout, supportedStreamProtocols)
|
remotecommand.ServeExec(w, req, p, fmt.Sprintf("%s-%s", namespace, pod), "", container, command, streamOpts, idleTimeout, streamCreationTimeout, supportedStreamProtocols)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user