|
|
@@ -5,8 +5,10 @@ import (
|
|
|
"net/http"
|
|
|
"net/url"
|
|
|
|
|
|
+ "github.com/go-chi/chi"
|
|
|
"github.com/porter-dev/porter/internal/kubernetes"
|
|
|
|
|
|
+ "github.com/gorilla/websocket"
|
|
|
"github.com/porter-dev/porter/internal/forms"
|
|
|
)
|
|
|
|
|
|
@@ -16,6 +18,11 @@ const (
|
|
|
ErrK8sValidate
|
|
|
)
|
|
|
|
|
|
+var upgrader = websocket.Upgrader{
|
|
|
+ ReadBufferSize: 1024,
|
|
|
+ WriteBufferSize: 1024,
|
|
|
+}
|
|
|
+
|
|
|
// HandleListNamespaces retrieves a list of namespaces
|
|
|
func (app *App) HandleListNamespaces(w http.ResponseWriter, r *http.Request) {
|
|
|
session, err := app.store.Get(r, app.cookieName)
|
|
|
@@ -69,3 +76,76 @@ func (app *App) HandleListNamespaces(w http.ResponseWriter, r *http.Request) {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+// HandleGetPodLogs returns real-time logs of the pod via websockets
|
|
|
+func (app *App) HandleGetPodLogs(w http.ResponseWriter, r *http.Request) {
|
|
|
+ // get session to retrieve correct kubeconfig
|
|
|
+ session, err := app.store.Get(r, app.cookieName)
|
|
|
+
|
|
|
+ // get path parameters
|
|
|
+ namespace := chi.URLParam(r, "namespace")
|
|
|
+ podName := chi.URLParam(r, "name")
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ app.handleErrorFormDecoding(err, ErrReleaseDecode, w)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ vals, err := url.ParseQuery(r.URL.RawQuery)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ app.handleErrorFormDecoding(err, ErrReleaseDecode, w)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // get the filter options
|
|
|
+ form := &forms.K8sForm{
|
|
|
+ OutOfClusterConfig: &kubernetes.OutOfClusterConfig{},
|
|
|
+ }
|
|
|
+ form.PopulateK8sOptionsFromQueryParams(vals)
|
|
|
+
|
|
|
+ if sessID, ok := session.Values["user_id"].(uint); ok {
|
|
|
+ form.PopulateK8sOptionsFromUserID(sessID, app.repo.User)
|
|
|
+ }
|
|
|
+
|
|
|
+ // validate the form
|
|
|
+ if err := app.validator.Struct(form); err != nil {
|
|
|
+ app.handleErrorFormValidation(err, ErrK8sValidate, w)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // create a new agent
|
|
|
+ var agent *kubernetes.Agent
|
|
|
+
|
|
|
+ if app.testing {
|
|
|
+ agent = app.TestAgents.K8sAgent
|
|
|
+ } else {
|
|
|
+ agent, err = kubernetes.GetAgentOutOfClusterConfig(form.OutOfClusterConfig)
|
|
|
+ }
|
|
|
+
|
|
|
+ // allow all hosts for now
|
|
|
+ upgrader.CheckOrigin = func(r *http.Request) bool { return true }
|
|
|
+
|
|
|
+ // upgrade to websocket.
|
|
|
+ conn, err := upgrader.Upgrade(w, r, nil)
|
|
|
+ if err != nil {
|
|
|
+ app.handleErrorUpgradeWebsocket(err, w)
|
|
|
+ }
|
|
|
+
|
|
|
+ err = agent.GetPodLogs(namespace, podName, conn)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ app.handleErrorWebsocketWrite(err, w)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ app.handleErrorFormValidation(err, ErrK8sValidate, w)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := json.NewEncoder(w).Encode(logs); err != nil {
|
|
|
+ app.handleErrorFormDecoding(err, ErrK8sDecode, w)
|
|
|
+ return
|
|
|
+ }
|
|
|
+}
|