From 5f29d379b126e34747b18c6582f3850cf22c1694 Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Tue, 13 Dec 2022 11:17:18 -0500 Subject: [PATCH] separate out 'proxy' backend mode from public sharing (#95) --- cmd/zrok/share_public.go | 75 ++++++++++++++++++++++++++------------- cmd/zrok/util.go | 4 +++ endpoints/backend/http.go | 8 +++-- 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/cmd/zrok/share_public.go b/cmd/zrok/share_public.go index e7852e9f..e847fc18 100644 --- a/cmd/zrok/share_public.go +++ b/cmd/zrok/share_public.go @@ -32,33 +32,44 @@ type sharePublicCommand struct { quiet bool basicAuth []string frontendSelection []string + backendMode string cmd *cobra.Command } func newSharePublicCommand() *sharePublicCommand { cmd := &cobra.Command{ - Use: "public ", - Short: "Share a target endpoint publicly", + Use: "public ", + Short: "Share a target resource publicly", Args: cobra.ExactArgs(1), } command := &sharePublicCommand{cmd: cmd} cmd.Flags().BoolVarP(&command.quiet, "quiet", "q", false, "Disable TUI 'chrome' for quiet operation") cmd.Flags().StringArrayVar(&command.basicAuth, "basic-auth", []string{}, "Basic authentication users (,...)") cmd.Flags().StringArrayVar(&command.frontendSelection, "frontends", []string{"public"}, "Selected frontends to use for the share") + cmd.Flags().StringVar(&command.backendMode, "backend-mode", "proxy", "The backend mode {proxy, web}") cmd.Run = command.run return command } func (self *sharePublicCommand) run(_ *cobra.Command, args []string) { - targetEndpoint, err := url.Parse(args[0]) - if err != nil { - if !panicInstead { - showError("invalid target endpoint URL", err) + var target string + + switch self.backendMode { + case "proxy": + targetEndpoint, err := url.Parse(args[0]) + if err != nil { + if !panicInstead { + showError("invalid target endpoint URL", err) + } + panic(err) } - panic(err) - } - if targetEndpoint.Scheme == "" { - targetEndpoint.Scheme = "https" + if targetEndpoint.Scheme == "" { + targetEndpoint.Scheme = "https" + } + target = targetEndpoint.String() + + default: + showError(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web}", self.backendMode), nil) } if !self.quiet { @@ -90,7 +101,7 @@ func (self *sharePublicCommand) run(_ *cobra.Command, args []string) { } cfg := &backend.Config{ IdentityPath: zif, - EndpointAddress: targetEndpoint.String(), + EndpointAddress: target, } zrok, err := zrokdir.ZrokClient(env.ApiEndpoint) @@ -141,23 +152,22 @@ func (self *sharePublicCommand) run(_ *cobra.Command, args []string) { os.Exit(0) }() - httpProxy, err := backend.NewHTTP(cfg) - if err != nil { - ui.Close() - if !panicInstead { - showError("unable to create http backend", err) - } - panic(err) - } - - go func() { - if err := httpProxy.Run(); err != nil { + var bh backendHandler + switch self.backendMode { + case "proxy": + bh, err = self.proxyBackendMode(cfg) + if err != nil { + ui.Close() if !panicInstead { - showError("unable to run http proxy", err) + showError("unable to create proxy backend handler", err) } panic(err) } - }() + + default: + ui.Close() + showError("invalid backend mode", nil) + } if !self.quiet { ui.Clear() @@ -206,7 +216,7 @@ func (self *sharePublicCommand) run(_ *cobra.Command, args []string) { } case <-ticker: - currentRequests := float64(httpProxy.Requests()) + currentRequests := float64(bh.Requests()()) deltaRequests := currentRequests - lastRequests requestData = append(requestData, deltaRequests) lastRequests = currentRequests @@ -227,6 +237,21 @@ func (self *sharePublicCommand) run(_ *cobra.Command, args []string) { } } +func (self *sharePublicCommand) proxyBackendMode(cfg *backend.Config) (backendHandler, error) { + httpProxy, err := backend.NewHTTP(cfg) + if err != nil { + return nil, errors.Wrap(err, "error creating http proxy backend") + } + + go func() { + if err := httpProxy.Run(); err != nil { + logrus.Errorf("error running http proxy backend: %v", err) + } + }() + + return httpProxy, nil +} + func (self *sharePublicCommand) destroy(id string, cfg *backend.Config, zrok *rest_client_zrok.Zrok, auth runtime.ClientAuthInfoWriter) { logrus.Debugf("shutting down '%v'", cfg.Service) req := service.NewUnshareParams() diff --git a/cmd/zrok/util.go b/cmd/zrok/util.go index 248b43f8..be53c919 100644 --- a/cmd/zrok/util.go +++ b/cmd/zrok/util.go @@ -6,6 +6,10 @@ import ( "os" ) +type backendHandler interface { + Requests() func() int32 +} + func mustGetAdminAuth() runtime.ClientAuthInfoWriter { adminToken := os.Getenv("ZROK_ADMIN_TOKEN") if adminToken == "" { diff --git a/endpoints/backend/http.go b/endpoints/backend/http.go index af33c572..c5e87908 100644 --- a/endpoints/backend/http.go +++ b/endpoints/backend/http.go @@ -23,7 +23,7 @@ type Config struct { type httpBind struct { cfg *Config - Requests func() int32 + requests func() int32 listener edge.Listener handler http.Handler } @@ -50,7 +50,7 @@ func NewHTTP(cfg *Config) (*httpBind, error) { handler := util.NewProxyHandler(proxy) return &httpBind{ cfg: cfg, - Requests: handler.Requests, + requests: handler.Requests, listener: listener, handler: handler, }, nil @@ -63,6 +63,10 @@ func (self *httpBind) Run() error { return nil } +func (self *httpBind) Requests() func() int32 { + return self.requests +} + func newReverseProxy(target string) (*httputil.ReverseProxy, error) { targetURL, err := url.Parse(target) if err != nil {