From 2b12f1c6cd9d3bafb677b50979fe7e5533f62eaf Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Wed, 30 Aug 2023 14:10:48 -0400 Subject: [PATCH] caddy integration for reserved shares (#392); sdk refactoring; cleanup and tweaks --- cmd/zrok/reserve.go | 64 +++++++------------ cmd/zrok/sharePrivate.go | 11 ++-- cmd/zrok/shareReserved.go | 131 ++++++++++++++++++++++++++------------ 3 files changed, 122 insertions(+), 84 deletions(-) diff --git a/cmd/zrok/reserve.go b/cmd/zrok/reserve.go index 997bac2fb..c0db42a69 100644 --- a/cmd/zrok/reserve.go +++ b/cmd/zrok/reserve.go @@ -1,16 +1,12 @@ package main import ( - httptransport "github.com/go-openapi/runtime/client" + "fmt" "github.com/openziti/zrok/environment" - "github.com/openziti/zrok/rest_client_zrok/share" - "github.com/openziti/zrok/rest_model_zrok" "github.com/openziti/zrok/sdk" "github.com/openziti/zrok/tui" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "strings" ) func init() { @@ -33,7 +29,7 @@ func newReserveCommand() *reserveCommand { command := &reserveCommand{cmd: cmd} 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.Flags().StringVar(&command.backendMode, "backend-mode", "proxy", "The backend mode {proxy, web, , caddy}") cmd.Run = command.run return command } @@ -58,6 +54,18 @@ func (cmd *reserveCommand) run(_ *cobra.Command, args []string) { case "web": target = args[1] + + case "tcpTunnel": + target = args[1] + + case "udpTunnel": + target = args[1] + + case "caddy": + target = args[1] + + default: + tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, tcpTunnel, udpTunnel, caddy}", cmd.backendMode), nil) } env, err := environment.LoadRoot() @@ -72,49 +80,25 @@ func (cmd *reserveCommand) run(_ *cobra.Command, args []string) { tui.Error("unable to load environment; did you 'zrok enable'?", nil) } - zrok, err := env.Client() - if err != nil { - if !panicInstead { - tui.Error("unable to create zrok client", err) - } - panic(err) - } - auth := httptransport.APIKeyAuth("X-TOKEN", "header", env.Environment().Token) - req := share.NewShareParams() - req.Body = &rest_model_zrok.ShareRequest{ - EnvZID: env.Environment().ZitiIdentity, - ShareMode: string(shareMode), - BackendMode: cmd.backendMode, - BackendProxyEndpoint: target, - AuthScheme: string(sdk.None), - Reserved: true, + req := &sdk.ShareRequest{ + BackendMode: sdk.BackendMode(cmd.backendMode), + ShareMode: shareMode, + Auth: cmd.basicAuth, + Target: target, } if shareMode == sdk.PublicShareMode { - req.Body.FrontendSelection = cmd.frontendSelection + req.Frontends = cmd.frontendSelection } - if len(cmd.basicAuth) > 0 { - logrus.Infof("configuring basic auth") - req.Body.AuthScheme = string(sdk.Basic) - for _, pair := range cmd.basicAuth { - tokens := strings.Split(pair, ":") - if len(tokens) == 2 { - req.Body.AuthUsers = append(req.Body.AuthUsers, &rest_model_zrok.AuthUser{Username: strings.TrimSpace(tokens[0]), Password: strings.TrimSpace(tokens[1])}) - } else { - panic(errors.Errorf("invalid username:password pair '%v'", pair)) - } - } - } - - resp, err := zrok.Share.Share(req, auth) + shr, err := sdk.CreateShare(env, req) if err != nil { if !panicInstead { - tui.Error("unable to create tunnel", err) + tui.Error("unable to create share", err) } panic(err) } - logrus.Infof("your reserved share token is '%v'", resp.Payload.ShrToken) - for _, fpe := range resp.Payload.FrontendProxyEndpoints { + logrus.Infof("your reserved share token is '%v'", shr.Token) + for _, fpe := range shr.FrontendEndpoints { logrus.Infof("reserved frontend endpoint: %v", fpe) } } diff --git a/cmd/zrok/sharePrivate.go b/cmd/zrok/sharePrivate.go index 961964045..1555ee699 100644 --- a/cmd/zrok/sharePrivate.go +++ b/cmd/zrok/sharePrivate.go @@ -70,9 +70,10 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { case "caddy": target = args[0] + cmd.headless = true default: - tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, tcpTunnel}", cmd.backendMode), nil) + tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, tcpTunnel, udpTunnel, caddy}", cmd.backendMode), nil) } root, err := environment.LoadRoot() @@ -160,7 +161,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := proxy.NewCaddyWebBackend(cfg) if err != nil { if !panicInstead { - tui.Error("unable to create web backend handler", err) + tui.Error("error creating web backend", err) } panic(err) } @@ -182,7 +183,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := tcpTunnel.NewBackend(cfg) if err != nil { if !panicInstead { - tui.Error("unable to create tcpTunnel backend", err) + tui.Error("error creating tcpTunnel backend", err) } panic(err) } @@ -204,7 +205,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := udpTunnel.NewBackend(cfg) if err != nil { if !panicInstead { - tui.Error("unable to create udpTunnel backend", err) + tui.Error("error creating udpTunnel backend", err) } panic(err) } @@ -225,7 +226,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := proxy.NewCaddyfileBackend(cfg) if err != nil { if !panicInstead { - tui.Error("unable to create caddy backend", err) + tui.Error("error creating caddy backend", err) } panic(err) } diff --git a/cmd/zrok/shareReserved.go b/cmd/zrok/shareReserved.go index d4c2c6946..c4e33bb72 100644 --- a/cmd/zrok/shareReserved.go +++ b/cmd/zrok/shareReserved.go @@ -6,13 +6,14 @@ import ( httptransport "github.com/go-openapi/runtime/client" "github.com/openziti/zrok/endpoints" "github.com/openziti/zrok/endpoints/proxy" + "github.com/openziti/zrok/endpoints/tcpTunnel" + "github.com/openziti/zrok/endpoints/udpTunnel" "github.com/openziti/zrok/environment" "github.com/openziti/zrok/rest_client_zrok/metadata" "github.com/openziti/zrok/rest_client_zrok/share" "github.com/openziti/zrok/rest_model_zrok" "github.com/openziti/zrok/sdk" "github.com/openziti/zrok/tui" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -45,7 +46,7 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { shrToken := args[0] var target string - env, err := environment.LoadRoot() + root, err := environment.LoadRoot() if err != nil { if !panicInstead { tui.Error("error loading environment", err) @@ -53,18 +54,18 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { panic(err) } - if !env.IsEnabled() { + if !root.IsEnabled() { tui.Error("unable to load environment; did you 'zrok enable'?", nil) } - zrok, err := env.Client() + zrok, err := root.Client() if err != nil { if !panicInstead { tui.Error("unable to create zrok client", err) } panic(err) } - auth := httptransport.APIKeyAuth("X-TOKEN", "header", env.Environment().Token) + auth := httptransport.APIKeyAuth("X-TOKEN", "header", root.Environment().Token) req := metadata.NewGetShareDetailParams() req.ShrToken = shrToken resp, err := zrok.Metadata.GetShareDetail(req, auth) @@ -78,8 +79,11 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { if target == "" { target = resp.Payload.BackendProxyEndpoint } + if sdk.BackendMode(resp.Payload.BackendMode) == sdk.CaddyBackendMode { + cmd.headless = true + } - zif, err := env.ZitiIdentityNamed(env.EnvironmentIdentityName()) + zif, err := root.ZitiIdentityNamed(root.EnvironmentIdentityName()) if err != nil { if !panicInstead { tui.Error("unable to load ziti identity configuration", err) @@ -129,7 +133,8 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { Insecure: cmd.insecure, Requests: requestsChan, } - _, err := cmd.proxyBackendMode(cfg) + + be, err := proxy.NewBackend(cfg) if err != nil { if !panicInstead { tui.Error("unable to create proxy backend handler", err) @@ -137,6 +142,12 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { panic(err) } + go func() { + if err := be.Run(); err != nil { + logrus.Errorf("error running http proxy backend: %v", err) + } + }() + case "web": cfg := &proxy.CaddyWebBackendConfig{ IdentityPath: zif, @@ -144,14 +155,86 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { ShrToken: shrToken, Requests: requestsChan, } - _, err := cmd.webBackendMode(cfg) + + be, err := proxy.NewCaddyWebBackend(cfg) + if err != nil { + if !panicInstead { + tui.Error("error creating web backend", err) + } + panic(err) + } + + go func() { + if err := be.Run(); err != nil { + logrus.Errorf("error running http web backend: %v", err) + } + }() + + case "tcpTunnel": + cfg := &tcpTunnel.BackendConfig{ + IdentityPath: zif, + EndpointAddress: target, + ShrToken: shrToken, + RequestsChan: requestsChan, + } + + be, err := tcpTunnel.NewBackend(cfg) if err != nil { if !panicInstead { - tui.Error("unable to create web backend handler", err) + tui.Error("error creating tcpTunnel backend", err) } panic(err) } + go func() { + if err := be.Run(); err != nil { + logrus.Errorf("error running tcpTunnel backend: %v", err) + } + }() + + case "udpTunnel": + cfg := &udpTunnel.BackendConfig{ + IdentityPath: zif, + EndpointAddress: target, + ShrToken: shrToken, + RequestsChan: requestsChan, + } + + be, err := udpTunnel.NewBackend(cfg) + if err != nil { + if !panicInstead { + tui.Error("error creating udpTunnel backend", err) + } + panic(err) + } + + go func() { + if err := be.Run(); err != nil { + logrus.Errorf("error running udpTunnel backend: %v", err) + } + }() + + case "caddy": + cfg := &proxy.CaddyfileBackendConfig{ + CaddyfilePath: target, + Shr: &sdk.Share{Token: shrToken, FrontendEndpoints: []string{resp.Payload.FrontendEndpoint}}, + Requests: requestsChan, + } + + be, err := proxy.NewCaddyfileBackend(cfg) + if err != nil { + if !panicInstead { + tui.Error("error creating caddy backend", err) + } + panic(err) + } + + go func() { + if err := be.Run(); err != nil { + logrus.Errorf("error running caddy backend: %v", err) + } + }() + default: tui.Error("invalid backend mode", nil) } @@ -191,33 +274,3 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { close(requestsChan) } } - -func (cmd *shareReservedCommand) proxyBackendMode(cfg *proxy.BackendConfig) (endpoints.RequestHandler, error) { - be, err := proxy.NewBackend(cfg) - if err != nil { - return nil, errors.Wrap(err, "error creating http proxy backend") - } - - go func() { - if err := be.Run(); err != nil { - logrus.Errorf("error running http proxy backend: %v", err) - } - }() - - return be, nil -} - -func (cmd *shareReservedCommand) webBackendMode(cfg *proxy.CaddyWebBackendConfig) (endpoints.RequestHandler, error) { - be, err := proxy.NewCaddyWebBackend(cfg) - if err != nil { - return nil, errors.Wrap(err, "error creating http web backend") - } - - go func() { - if err := be.Run(); err != nil { - logrus.Errorf("error running http web backend: %v", err) - } - }() - - return be, nil -}