From c9234cb62a9c4465a69abd2a172b726a8dc96fd3 Mon Sep 17 00:00:00 2001 From: Benedikt Iltisberger Date: Fri, 27 Oct 2023 14:45:17 +0200 Subject: [PATCH] feat: proxy support enabled. --- README.md | 8 +++++++ cmd/proxy.go | 22 ++++++++++++++---- cmd/upgrade.go | 3 +++ kubernetes/addResources.go | 6 ++++- kubernetes/portforward.go | 46 ++++++++++++++++++++++++++++++++++++++ welcome.md | 8 ++++++- 6 files changed, 87 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index edcd5d7..73e2fe8 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,14 @@ After successfully installing punq, you're just a few steps away from harnessing To install punq on your cluster within the current context and set up ingress routing, enabling you to access punq via your custom domain: +### Without Ingress (local / not exposed to the internet) + +``` +punq install +punq proxy +``` + +### With Ingress ``` punq install -i punq.yourdomain.com ``` diff --git a/cmd/proxy.go b/cmd/proxy.go index fdd25d8..fa24436 100644 --- a/cmd/proxy.go +++ b/cmd/proxy.go @@ -31,7 +31,7 @@ var proxyCmd = &cobra.Command{ // FORWARD BACKEND readyBackendCh := make(chan struct{}) stopBackendCh := make(chan struct{}, 1) - backendUrl := fmt.Sprintf("http://%s:%d/version", utils.CONFIG.Backend.Host, utils.CONFIG.Backend.Port) + backendUrl := fmt.Sprintf("http://%s:%d", utils.CONFIG.Backend.Host, utils.CONFIG.Backend.Port) go kubernetes.StartPortForward(utils.CONFIG.Backend.Port, utils.CONFIG.Backend.Port, readyBackendCh, stopBackendCh, &contextId) // FORWARD FRONTEND @@ -40,6 +40,12 @@ var proxyCmd = &cobra.Command{ frontendUrl := fmt.Sprintf("http://%s:%d", utils.CONFIG.Frontend.Host, utils.CONFIG.Frontend.Port) go kubernetes.StartPortForward(utils.CONFIG.Frontend.Port, utils.CONFIG.Frontend.Port, readyFrontendCh, stopFrontendCh, &contextId) + // FORWARD WEBSOCKET + readyWebsocketCh := make(chan struct{}) + stopWebsocketCh := make(chan struct{}, 1) + websocketUrl := fmt.Sprintf("ws://%s:%d", utils.CONFIG.Websocket.Host, utils.CONFIG.Websocket.Port) + go kubernetes.StartPortForward(utils.CONFIG.Websocket.Port, utils.CONFIG.Websocket.Port, readyWebsocketCh, stopWebsocketCh, &contextId) + select { case <-readyBackendCh: fmt.Printf("Backend %s is ready! 🚀🚀🚀\n", backendUrl) @@ -50,14 +56,23 @@ var proxyCmd = &cobra.Command{ select { case <-readyFrontendCh: - fmt.Printf("Frontend %s is ready! 🚀🚀🚀\n", frontendUrl) - utils.OpenBrowser(frontendUrl) + utils.OpenBrowser("http://localhost:8888") break case <-stopFrontendCh: break } + select { + case <-readyWebsocketCh: + fmt.Printf("Websocket %s is ready! 🚀🚀🚀\n", websocketUrl) + break + case <-stopWebsocketCh: + break + } + + kubernetes.Proxy(backendUrl, frontendUrl, websocketUrl) + quit := make(chan os.Signal) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit @@ -65,6 +80,5 @@ var proxyCmd = &cobra.Command{ } func init() { - proxyCmd.Hidden = true rootCmd.AddCommand(proxyCmd) } diff --git a/cmd/upgrade.go b/cmd/upgrade.go index ad9fa9d..7f2b377 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -52,6 +52,9 @@ var updateOperatorImageCmd = &cobra.Command{ } imageName := fmt.Sprintf("ghcr.io/mogenius/punq:%s", vers) + if utils.CONFIG.Misc.Stage != "production" { + imageName = fmt.Sprintf("ghcr.io/mogenius/punq-dev:%s", vers) + } err = kubernetes.UpdateDeploymentImage(utils.CONFIG.Kubernetes.OwnNamespace, version.Name, imageName, nil) if err != nil { fmt.Printf("Error: %s\n", err.Error()) diff --git a/kubernetes/addResources.go b/kubernetes/addResources.go index a63d037..b22496d 100644 --- a/kubernetes/addResources.go +++ b/kubernetes/addResources.go @@ -305,7 +305,11 @@ func addDeployment(provider *KubeProvider) { deploymentContainer.WithName(version.Name) deploymentContainer.WithImage(version.OperatorImage) - deploymentContainer.WithPorts(applyconfcore.ContainerPort().WithContainerPort(int32(utils.CONFIG.Backend.Port)).WithContainerPort(int32(utils.CONFIG.Frontend.Port)).WithContainerPort(int32(utils.CONFIG.Websocket.Port))) + deploymentContainer.WithPorts( + applyconfcore.ContainerPort().WithContainerPort(int32(utils.CONFIG.Backend.Port)), + applyconfcore.ContainerPort().WithContainerPort(int32(utils.CONFIG.Frontend.Port)), + applyconfcore.ContainerPort().WithContainerPort(int32(utils.CONFIG.Websocket.Port)), + ) envVars := []applyconfcore.EnvVarApplyConfiguration{} envVars = append(envVars, applyconfcore.EnvVarApplyConfiguration{ diff --git a/kubernetes/portforward.go b/kubernetes/portforward.go index 5325d66..5ce48ed 100644 --- a/kubernetes/portforward.go +++ b/kubernetes/portforward.go @@ -7,6 +7,7 @@ import ( "bytes" "fmt" "net/http" + "net/http/httputil" "net/url" "os" "os/signal" @@ -112,3 +113,48 @@ func portForwardAPod(req PortForwardAPodRequest, contextId *string) error { } return fw.ForwardPorts() } + +func Proxy(backendUrl string, frontendUrl string, websocketUrl string) { + localPort := ":8888" + + backendURL, err := url.Parse(backendUrl) + if err != nil { + utils.FatalError(fmt.Sprintf("Error parsing backend url: %s", err.Error())) + } + frontendURL, err := url.Parse(frontendUrl) + if err != nil { + utils.FatalError(fmt.Sprintf("Error parsing frontend url: %s", err.Error())) + } + websocketURL, err := url.Parse(websocketUrl) + if err != nil { + utils.FatalError(fmt.Sprintf("Error parsing websocket url: %s", err.Error())) + } + + backendProxy := httputil.NewSingleHostReverseProxy(backendURL) + frontendProxy := httputil.NewSingleHostReverseProxy(frontendURL) + websocketProxy := httputil.NewSingleHostReverseProxy(websocketURL) + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + orig := r.URL + fmt.Printf("FRONTEND: localhost%s%s -> %s%s\n", localPort, orig, frontendURL, r.URL) + frontendProxy.ServeHTTP(w, r) + }) + + http.HandleFunc("/backend/", func(w http.ResponseWriter, r *http.Request) { + orig := r.URL + r.URL.Path = strings.Replace(r.URL.Path, "/backend", "", 1) + fmt.Printf("BACKEND : localhost%s%s -> %s%s\n", localPort, orig, backendURL, r.URL) + backendProxy.ServeHTTP(w, r) + }) + + http.HandleFunc("/websocket", func(w http.ResponseWriter, r *http.Request) { + orig := r.URL + r.URL.Path = strings.Replace(r.URL.Path, "/websocket", "", 1) + fmt.Printf("WEBSOCKET: localhost%s%s -> %s%s\n", localPort, orig, websocketURL, r.URL) + websocketProxy.ServeHTTP(w, r) + }) + + if err = http.ListenAndServe(localPort, nil); err != nil { + utils.FatalError(fmt.Sprintf("Error starting proxy: %s", err.Error())) + } +} diff --git a/welcome.md b/welcome.md index 547e1c4..91ea40f 100644 --- a/welcome.md +++ b/welcome.md @@ -1,5 +1,11 @@ # Install punq on your cluster in your current context. This will also set up the ingress to deliver punq on your own domain. You'll be asked to confirm with "Y". -punq install -i punq.yourdomain.com +## Without Ingress (local / not exposed to the internet): + punq install + punq proxy + +## With Ingress + punq install -i punq.yourdomain.com + open https://punq.yourdomain.com - In your domain's DNS settings, add an A-Record for the punq domain which points to your cluster loadbalancer IP, e.g. A: 123.123.123.123 -> punq.yourdomain.com. - Open punq in your browser.