mirror of
https://github.com/openziti/zrok.git
synced 2024-11-07 08:44:14 +01:00
merged tui for tcpTunnel (#307)
This commit is contained in:
parent
74fd8d9956
commit
28916e8d2a
@ -6,6 +6,7 @@ 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/rest_client_zrok"
|
||||
"github.com/openziti/zrok/rest_client_zrok/share"
|
||||
"github.com/openziti/zrok/rest_model_zrok"
|
||||
@ -48,14 +49,6 @@ func newAccessPrivateCommand() *accessPrivateCommand {
|
||||
func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
shrToken := args[0]
|
||||
|
||||
endpointUrl, err := url.Parse("http://" + cmd.bindAddress)
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("invalid endpoint address", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
zrd, err := zrokdir.Load()
|
||||
if err != nil {
|
||||
tui.Error("unable to load zrokdir", err)
|
||||
@ -88,10 +81,62 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
}
|
||||
logrus.Infof("allocated frontend '%v'", accessResp.Payload.FrontendToken)
|
||||
|
||||
protocol := "http://"
|
||||
switch accessResp.Payload.BackendMode {
|
||||
case "tcpTunnel":
|
||||
protocol = "tcp://"
|
||||
}
|
||||
|
||||
endpointUrl, err := url.Parse(protocol + cmd.bindAddress)
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("invalid endpoint address", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
requests := make(chan *endpoints.Request, 1024)
|
||||
if accessResp.Payload.BackendMode == "tcpTunnel" {
|
||||
fe, err := tcpTunnel.NewFrontend(&tcpTunnel.FrontendConfig{
|
||||
BindAddress: cmd.bindAddress,
|
||||
IdentityName: "backend",
|
||||
ShrToken: args[0],
|
||||
RequestsChan: requests,
|
||||
})
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("unable to create private frontend", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
if err := fe.Run(); err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("error starting frontend", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
} else {
|
||||
cfg := proxy.DefaultFrontendConfig("backend")
|
||||
cfg.ShrToken = shrToken
|
||||
cfg.Address = cmd.bindAddress
|
||||
cfg.RequestsChan = make(chan *endpoints.Request, 1024)
|
||||
cfg.RequestsChan = requests
|
||||
fe, err := proxy.NewFrontend(cfg)
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("unable to create private frontend", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
if err := fe.Run(); err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("unable to run frontend", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||
@ -101,27 +146,11 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
frontend, err := proxy.NewFrontend(cfg)
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("unable to create private frontend", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
go func() {
|
||||
if err := frontend.Run(); err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("unable to run frontend", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if cmd.headless {
|
||||
logrus.Infof("access the zrok share at the followind endpoint: %v", endpointUrl.String())
|
||||
for {
|
||||
select {
|
||||
case req := <-cfg.RequestsChan:
|
||||
case req := <-requests:
|
||||
logrus.Infof("%v -> %v %v", req.RemoteAddr, req.Method, req.Path)
|
||||
}
|
||||
}
|
||||
@ -135,7 +164,7 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case req := <-cfg.RequestsChan:
|
||||
case req := <-requests:
|
||||
if req != nil {
|
||||
prg.Send(req)
|
||||
}
|
||||
@ -147,9 +176,8 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
tui.Error("An error occurred", err)
|
||||
}
|
||||
|
||||
close(cfg.RequestsChan)
|
||||
close(requests)
|
||||
cmd.destroy(accessResp.Payload.FrontendToken, zrd.Env.ZId, shrToken, zrok, auth)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,107 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/go-openapi/runtime"
|
||||
httptransport "github.com/go-openapi/runtime/client"
|
||||
"github.com/openziti/zrok/endpoints/tcpTunnel"
|
||||
"github.com/openziti/zrok/rest_client_zrok"
|
||||
"github.com/openziti/zrok/rest_client_zrok/share"
|
||||
"github.com/openziti/zrok/rest_model_zrok"
|
||||
"github.com/openziti/zrok/tui"
|
||||
"github.com/openziti/zrok/zrokdir"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
accessPrivateCmd.cmd.AddCommand(newAccessPrivateTunnelCommand().cmd)
|
||||
}
|
||||
|
||||
type accessPrivateTunnelCommand struct {
|
||||
bindAddress string
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
func newAccessPrivateTunnelCommand() *accessPrivateTunnelCommand {
|
||||
cmd := &cobra.Command{
|
||||
Use: "tunnel <shareToken>",
|
||||
Short: "Create a private tunnel frontend to access a share",
|
||||
Args: cobra.ExactArgs(1),
|
||||
}
|
||||
command := &accessPrivateTunnelCommand{cmd: cmd}
|
||||
cmd.Flags().StringVarP(&command.bindAddress, "bind", "b", "127.0.0.1:9191", "The address to bind the private tunnel")
|
||||
cmd.Run = command.run
|
||||
return command
|
||||
}
|
||||
|
||||
func (cmd *accessPrivateTunnelCommand) run(_ *cobra.Command, args []string) {
|
||||
zrd, err := zrokdir.Load()
|
||||
if err != nil {
|
||||
tui.Error("unable to load zrokdir", err)
|
||||
}
|
||||
|
||||
if zrd.Env == nil {
|
||||
tui.Error("unable to load environment; did you 'zrok enable'?", nil)
|
||||
}
|
||||
|
||||
zrok, err := zrd.Client()
|
||||
if err != nil {
|
||||
tui.Error("unable to create zrok client", err)
|
||||
}
|
||||
|
||||
auth := httptransport.APIKeyAuth("X-TOKEN", "header", zrd.Env.Token)
|
||||
req := share.NewAccessParams()
|
||||
req.Body = &rest_model_zrok.AccessRequest{
|
||||
ShrToken: args[0],
|
||||
EnvZID: zrd.Env.ZId,
|
||||
}
|
||||
accessResp, err := zrok.Share.Access(req, auth)
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("unable to access", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
logrus.Infof("allocated frontend '%v'", accessResp.Payload.FrontendToken)
|
||||
|
||||
c := make(chan os.Signal)
|
||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-c
|
||||
cmd.destroy(accessResp.Payload.FrontendToken, zrd.Env.ZId, args[0], zrok, auth)
|
||||
os.Exit(0)
|
||||
}()
|
||||
fe, err := tcpTunnel.NewFrontend(&tcpTunnel.FrontendConfig{
|
||||
BindAddress: cmd.bindAddress,
|
||||
IdentityName: "backend",
|
||||
ShrToken: args[0],
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := fe.Run(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for {
|
||||
time.Sleep(30 * 24 * time.Hour)
|
||||
}
|
||||
}
|
||||
|
||||
func (cmd *accessPrivateTunnelCommand) destroy(frontendName, envZId, shrToken string, zrok *rest_client_zrok.Zrok, auth runtime.ClientAuthInfoWriter) {
|
||||
logrus.Debugf("shutting down '%v'", shrToken)
|
||||
req := share.NewUnaccessParams()
|
||||
req.Body = &rest_model_zrok.UnaccessRequest{
|
||||
FrontendToken: frontendName,
|
||||
ShrToken: shrToken,
|
||||
EnvZID: envZId,
|
||||
}
|
||||
if _, err := zrok.Share.Unaccess(req, auth); err == nil {
|
||||
logrus.Debugf("shutdown complete")
|
||||
} else {
|
||||
logrus.Errorf("error shutting down: %v", err)
|
||||
}
|
||||
}
|
@ -43,7 +43,7 @@ func newSharePrivateCommand() *sharePrivateCommand {
|
||||
}
|
||||
command := &sharePrivateCommand{cmd: cmd}
|
||||
cmd.Flags().StringArrayVar(&command.basicAuth, "basic-auth", []string{}, "Basic authentication users (<username:password>,...")
|
||||
cmd.Flags().StringVar(&command.backendMode, "backend-mode", "proxy", "The backend mode {proxy, web, tunnel}")
|
||||
cmd.Flags().StringVar(&command.backendMode, "backend-mode", "proxy", "The backend mode {proxy, web, tcpTunnel}")
|
||||
cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless")
|
||||
cmd.Flags().BoolVar(&command.insecure, "insecure", false, "Enable insecure TLS certificate validation for <target>")
|
||||
cmd.Run = command.run
|
||||
@ -67,11 +67,11 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
case "web":
|
||||
target = args[0]
|
||||
|
||||
case "tunnel":
|
||||
case "tcpTunnel":
|
||||
target = args[0]
|
||||
|
||||
default:
|
||||
tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, tunnel}", cmd.backendMode), nil)
|
||||
tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, tcpTunnel}", cmd.backendMode), nil)
|
||||
}
|
||||
|
||||
zrd, err := zrokdir.Load()
|
||||
@ -172,7 +172,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
case "tunnel":
|
||||
case "tcpTunnel":
|
||||
cfg := &tcpTunnel.BackendConfig{
|
||||
IdentityPath: zif,
|
||||
EndpointAddress: target,
|
||||
@ -182,13 +182,13 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) {
|
||||
be, err := tcpTunnel.NewBackend(cfg)
|
||||
if err != nil {
|
||||
if !panicInstead {
|
||||
tui.Error("unable to create tunnel backend", err)
|
||||
tui.Error("unable to create tcpTunnel backend", err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
if err := be.Run(); err != nil {
|
||||
logrus.Errorf("error running tunnel backend: %v", err)
|
||||
logrus.Errorf("error running tcpTunnel backend: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -86,5 +86,8 @@ func (h *accessHandler) Handle(params share.AccessParams, principal *rest_model_
|
||||
return share.NewAccessInternalServerError()
|
||||
}
|
||||
|
||||
return share.NewAccessCreated().WithPayload(&rest_model_zrok.AccessResponse{FrontendToken: feToken})
|
||||
return share.NewAccessCreated().WithPayload(&rest_model_zrok.AccessResponse{
|
||||
FrontendToken: feToken,
|
||||
BackendMode: shr.BackendMode,
|
||||
})
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
-- +migrate Up
|
||||
|
||||
alter type backend_mode rename value 'dav' to 'tunnel';
|
||||
alter type backend_mode rename value 'dav' to 'tcpTunnel';
|
||||
alter type backend_mode add value 'udpTunnel';
|
@ -18,7 +18,7 @@ create table shares (
|
||||
constraint chk_z_id check (z_id <> ''),
|
||||
constraint chk_token check (token <> ''),
|
||||
constraint chk_share_mode check (share_mode == 'public' or share_mode == 'private'),
|
||||
constraint chk_backend_mode check (backend_mode == 'proxy' or backend_mode == 'web' or backend_mode == 'tunnel')
|
||||
constraint chk_backend_mode check (backend_mode == 'proxy' or backend_mode == 'web' or backend_mode == 'tcpTunnel' or backend_mode == 'udpTunnel')
|
||||
);
|
||||
insert into shares select * from shares_old;
|
||||
drop table shares_old;
|
||||
|
@ -62,12 +62,14 @@ func (b *Backend) handle(conn net.Conn) {
|
||||
if rConn, err := net.DialTCP("tcp", nil, rAddr); err == nil {
|
||||
go endpoints.TXer(conn, rConn)
|
||||
go endpoints.TXer(rConn, conn)
|
||||
if b.cfg.RequestsChan != nil {
|
||||
b.cfg.RequestsChan <- &endpoints.Request{
|
||||
Stamp: time.Now(),
|
||||
RemoteAddr: conn.RemoteAddr().String(),
|
||||
Method: "OPEN",
|
||||
Method: "ACCEPT",
|
||||
Path: rAddr.String(),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logrus.Errorf("error dialing '%v': %v", b.cfg.EndpointAddress, err)
|
||||
_ = conn.Close()
|
||||
|
@ -9,12 +9,14 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
type FrontendConfig struct {
|
||||
BindAddress string
|
||||
IdentityName string
|
||||
ShrToken string
|
||||
RequestsChan chan *endpoints.Request
|
||||
}
|
||||
|
||||
type Frontend struct {
|
||||
@ -53,7 +55,7 @@ func (f *Frontend) Run() error {
|
||||
for {
|
||||
if conn, err := l.Accept(); err == nil {
|
||||
go f.accept(conn)
|
||||
logrus.Infof("accepted tcp connection from '%v'", conn.RemoteAddr())
|
||||
logrus.Debugf("accepted tcp connection from '%v'", conn.RemoteAddr())
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
@ -64,7 +66,14 @@ func (f *Frontend) accept(conn net.Conn) {
|
||||
if zConn, err := f.zCtx.Dial(f.cfg.ShrToken); err == nil {
|
||||
go endpoints.TXer(conn, zConn)
|
||||
go endpoints.TXer(zConn, conn)
|
||||
logrus.Infof("accepted '%v' <=> '%v'", conn.RemoteAddr(), zConn.RemoteAddr())
|
||||
if f.cfg.RequestsChan != nil {
|
||||
f.cfg.RequestsChan <- &endpoints.Request{
|
||||
Stamp: time.Now(),
|
||||
RemoteAddr: conn.RemoteAddr().String(),
|
||||
Method: "ACCEPT",
|
||||
Path: f.cfg.ShrToken,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logrus.Errorf("error dialing '%v': %v", f.cfg.ShrToken, err)
|
||||
_ = conn.Close()
|
||||
|
@ -17,6 +17,9 @@ import (
|
||||
// swagger:model accessResponse
|
||||
type AccessResponse struct {
|
||||
|
||||
// backend mode
|
||||
BackendMode string `json:"backendMode,omitempty"`
|
||||
|
||||
// frontend token
|
||||
FrontendToken string `json:"frontendToken,omitempty"`
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ type ShareRequest struct {
|
||||
AuthUsers []*AuthUser `json:"authUsers"`
|
||||
|
||||
// backend mode
|
||||
// Enum: [proxy web tunnel]
|
||||
// Enum: [proxy web tcpTunnel udpTunnel]
|
||||
BackendMode string `json:"backendMode,omitempty"`
|
||||
|
||||
// backend proxy endpoint
|
||||
@ -100,7 +100,7 @@ var shareRequestTypeBackendModePropEnum []interface{}
|
||||
|
||||
func init() {
|
||||
var res []string
|
||||
if err := json.Unmarshal([]byte(`["proxy","web","tunnel"]`), &res); err != nil {
|
||||
if err := json.Unmarshal([]byte(`["proxy","web","tcpTunnel","udpTunnel"]`), &res); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, v := range res {
|
||||
@ -116,8 +116,11 @@ const (
|
||||
// ShareRequestBackendModeWeb captures enum value "web"
|
||||
ShareRequestBackendModeWeb string = "web"
|
||||
|
||||
// ShareRequestBackendModeTunnel captures enum value "tunnel"
|
||||
ShareRequestBackendModeTunnel string = "tunnel"
|
||||
// ShareRequestBackendModeTCPTunnel captures enum value "tcpTunnel"
|
||||
ShareRequestBackendModeTCPTunnel string = "tcpTunnel"
|
||||
|
||||
// ShareRequestBackendModeUDPTunnel captures enum value "udpTunnel"
|
||||
ShareRequestBackendModeUDPTunnel string = "udpTunnel"
|
||||
)
|
||||
|
||||
// prop value enum
|
||||
|
@ -852,6 +852,9 @@ func init() {
|
||||
"accessResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backendMode": {
|
||||
"type": "string"
|
||||
},
|
||||
"frontendToken": {
|
||||
"type": "string"
|
||||
}
|
||||
@ -1167,7 +1170,8 @@ func init() {
|
||||
"enum": [
|
||||
"proxy",
|
||||
"web",
|
||||
"tunnel"
|
||||
"tcpTunnel",
|
||||
"udpTunnel"
|
||||
]
|
||||
},
|
||||
"backendProxyEndpoint": {
|
||||
@ -2130,6 +2134,9 @@ func init() {
|
||||
"accessResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"backendMode": {
|
||||
"type": "string"
|
||||
},
|
||||
"frontendToken": {
|
||||
"type": "string"
|
||||
}
|
||||
@ -2445,7 +2452,8 @@ func init() {
|
||||
"enum": [
|
||||
"proxy",
|
||||
"web",
|
||||
"tunnel"
|
||||
"tcpTunnel",
|
||||
"udpTunnel"
|
||||
]
|
||||
},
|
||||
"backendProxyEndpoint": {
|
||||
|
@ -537,6 +537,8 @@ definitions:
|
||||
properties:
|
||||
frontendToken:
|
||||
type: string
|
||||
backendMode:
|
||||
type: string
|
||||
|
||||
authUser:
|
||||
type: object
|
||||
@ -771,7 +773,7 @@ definitions:
|
||||
type: string
|
||||
backendMode:
|
||||
type: string
|
||||
enum: ["proxy", "web", "tunnel"]
|
||||
enum: ["proxy", "web", "tcpTunnel", "udpTunnel"]
|
||||
backendProxyEndpoint:
|
||||
type: string
|
||||
authScheme:
|
||||
|
@ -14,6 +14,7 @@
|
||||
* @memberof module:types
|
||||
*
|
||||
* @property {string} frontendToken
|
||||
* @property {string} backendMode
|
||||
*/
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user