diff --git a/cmd/tunnel.go b/cmd/tunnel.go index 8688de7..0b92186 100644 --- a/cmd/tunnel.go +++ b/cmd/tunnel.go @@ -23,9 +23,8 @@ import ( func init() { addClientsPaginationFlags(tunnelListCmd) addClientsSearchFlag(tunnelListCmd) - tunnelListCmd.Flags().StringP(config.ClientNameFlag, "n", "", "[deprecated] Get tunnels of a client by name") - tunnelListCmd.Flags().StringP(config.ClientNamesFlag, "", "", "Get tunnels of a client by name(s)") - tunnelListCmd.Flags().StringP(controllers.ClientID, "c", "", "Get tunnels of a client by client id") + tunnelListCmd.Flags().StringP(config.ClientNameFlag, "n", "", "Get tunnels of a client by name") + tunnelListCmd.Flags().StringP(config.ClientID, "c", "", "Get tunnels of a client by client id") tunnelsCmd.AddCommand(tunnelListCmd) config.DefineCommandInputs(tunnelDeleteCmd, getDeleteTunnelRequirements()) diff --git a/internal/pkg/config/flags_tunnel.go b/internal/pkg/config/flags_tunnel.go index 69060bf..fb2ad78 100644 --- a/internal/pkg/config/flags_tunnel.go +++ b/internal/pkg/config/flags_tunnel.go @@ -34,20 +34,15 @@ func GetCreateTunnelParamReqs(isRDPUserRequired bool) []ParameterRequirement { ShortName: "c", IsRequired: true, IsEnabled: func(providedParams *options.ParameterBag) bool { - return providedParams.ReadString(ClientNameFlag, "") == "" && providedParams.ReadString(ClientNamesFlag, "") == "" + return providedParams.ReadString(ClientNameFlag, "") == "" }, Help: "Enter a client ID", }, { Field: ClientNameFlag, - Description: `[deprecated] client name, if no client id is provided`, + Description: `client name, if no client id is provided`, ShortName: "n", }, - { - Field: ClientNamesFlag, - Description: `client name(s), if no client id is provided`, - ShortName: "", - }, { Field: Local, Description: CreateTunnelLocalDescr, diff --git a/internal/pkg/controllers/commands_test.go b/internal/pkg/controllers/commands_test.go index 46962d7..ea81343 100644 --- a/internal/pkg/controllers/commands_test.go +++ b/internal/pkg/controllers/commands_test.go @@ -136,12 +136,12 @@ func TestInvalidInputForCommand(t *testing.T) { ExecutionHelper: &ExecutionHelper{}, } params := config.FromValues(map[string]string{ - ClientID: "", + config.ClientID: "", config.ClientNamesFlag: "", - Local: "lohost1:3300", - Remote: "rhost2:3344", - Scheme: utils.SSH, - CheckPort: "1", + config.Local: "lohost1:3300", + config.Remote: "rhost2:3344", + config.Scheme: utils.SSH, + config.CheckPort: "1", }) err := cc.Start(context.Background(), params) assert.EqualError(t, err, "no client ids, names or search provided") diff --git a/internal/pkg/controllers/tunnel.go b/internal/pkg/controllers/tunnel.go index 0452458..46e5013 100644 --- a/internal/pkg/controllers/tunnel.go +++ b/internal/pkg/controllers/tunnel.go @@ -21,25 +21,6 @@ import ( "github.com/cloudradar-monitoring/rportcli/internal/pkg/api" ) -const ( - ClientID = "client" - TunnelID = "tunnel" - Local = "local" - Remote = "remote" - Scheme = "scheme" - ACL = "acl" - CheckPort = "checkp" - IdleTimeoutMinutes = "idle-timeout-minutes" - SkipIdleTimeout = "skip-idle-timeout" - LaunchSSH = "launch-ssh" - LaunchRDP = "launch-rdp" - RDPWidth = "rdp-width" - RDPHeight = "rdp-height" - RDPUser = "rdp-user" - DefaultACL = "<>" - ForceDeletion = "force" -) - type TunnelRenderer interface { RenderTunnels(tunnels []*models.Tunnel) error RenderTunnel(t output.KvProvider) error @@ -72,8 +53,8 @@ func (tc *TunnelController) Tunnels(ctx context.Context, params *options.Paramet ctx, api.NewPaginationFromParams(params), api.NewFilters( - "id", params.ReadString(ClientID, ""), - "name", config.ReadNames(params), + "id", params.ReadString(config.ClientID, ""), + "name", params.ReadString(config.ClientNameFlag, ""), "*", params.ReadString(config.ClientSearchFlag, ""), ), ) @@ -100,8 +81,8 @@ func (tc *TunnelController) Delete(ctx context.Context, params *options.Paramete return err } - tunnelID := params.ReadString(TunnelID, "") - err = tc.Rport.DeleteTunnel(ctx, clientID, tunnelID, params.ReadBool(ForceDeletion, false)) + tunnelID := params.ReadString(config.TunnelID, "") + err = tc.Rport.DeleteTunnel(ctx, clientID, tunnelID, params.ReadBool(config.ForceDeletion, false)) if err != nil { if strings.Contains(err.Error(), "tunnel is still active") { return fmt.Errorf("%v, use -f to delete it anyway", err) @@ -120,18 +101,15 @@ func (tc *TunnelController) Delete(ctx context.Context, params *options.Paramete func (tc *TunnelController) getClientIDAndClientName( ctx context.Context, params *options.ParameterBag, -) (clientID, clientNames string, err error) { - clientID = params.ReadString(ClientID, "") - clientNames = params.ReadString(config.ClientNamesFlag, "") - if clientNames == "" { - clientNames = params.ReadString(config.ClientNameFlag, "") - } - if clientID == "" && clientNames == "" { - err = errors.New("no client id nor name provided") +) (clientID, clientName string, err error) { + clientID = params.ReadString(config.ClientID, "") + clientName = params.ReadString(config.ClientNameFlag, "") + if clientID == "" && clientName == "" { + err = errors.New("no client id or name provided") return } - if clientID != "" && clientNames != "" { - err = errors.New("both client id and name provided") + if clientID != "" && clientName != "" { + err = errors.New("both client id and name provided. Please provide one or the other") return } @@ -139,16 +117,16 @@ func (tc *TunnelController) getClientIDAndClientName( return } - clients, err := tc.Rport.Clients(ctx, api.NewPaginationWithLimit(2), api.NewFilters("name", clientNames)) + clients, err := tc.Rport.Clients(ctx, api.NewPaginationWithLimit(2), api.NewFilters("name", clientName)) if err != nil { return } if len(clients.Data) < 1 { - return "", "", fmt.Errorf("unknown client with name %q", clientNames) + return "", "", fmt.Errorf("unknown client with name %q", clientName) } if len(clients.Data) > 1 { - return "", "", fmt.Errorf("client with name %q is ambidguous, use a more precise name or use the client id", clientNames) + return "", "", fmt.Errorf("client with name %q is ambidguous, use a more precise name or use the client id", clientName) } client := clients.Data[0] @@ -161,8 +139,8 @@ func (tc *TunnelController) Create(ctx context.Context, params *options.Paramete return err } - acl := params.ReadString(ACL, "") - if (acl == "" || acl == DefaultACL) && tc.IPProvider != nil { + acl := params.ReadString(config.ACL, "") + if (acl == "" || acl == config.DefaultACL) && tc.IPProvider != nil { ip, e := tc.IPProvider.GetIP(ctx) if e != nil { logrus.Errorf("failed to fetch IP: %v", e) @@ -176,12 +154,12 @@ func (tc *TunnelController) Create(ctx context.Context, params *options.Paramete return err } - local := params.ReadString(Local, "") - checkPort := params.ReadString(CheckPort, "") - skipIdleTimeout := params.ReadBool(SkipIdleTimeout, false) + local := params.ReadString(config.Local, "") + checkPort := params.ReadString(config.CheckPort, "") + skipIdleTimeout := params.ReadBool(config.SkipIdleTimeout, false) idleTimeoutMinutes := 0 if !skipIdleTimeout { - idleTimeoutMinutes = params.ReadInt(IdleTimeoutMinutes, 0) + idleTimeoutMinutes = params.ReadInt(config.IdleTimeoutMinutes, 0) } tunResp, err := tc.Rport.CreateTunnel( ctx, @@ -217,17 +195,17 @@ func (tc *TunnelController) Create(ctx context.Context, params *options.Paramete return err } - launchSSHStr := params.ReadString(LaunchSSH, "") - shouldLaunchRDP := params.ReadBool(LaunchRDP, false) + launchSSHStr := params.ReadString(config.LaunchSSH, "") + shouldLaunchRDP := params.ReadBool(config.LaunchRDP, false) return tc.launchHelperFlowIfNeeded(ctx, launchSSHStr, clientID, clientName, shouldLaunchRDP, tunnelCreated, params) } func (tc *TunnelController) resolveRemoteAddrAndScheme(params *options.ParameterBag) (remotePortAndHostStr, scheme string, err error) { - remotePortAndHostStr = params.ReadString(Remote, "") + remotePortAndHostStr = params.ReadString(config.Remote, "") remotePortInt, _ := utils.ExtractPortAndHost(remotePortAndHostStr) - scheme = params.ReadString(Scheme, "") + scheme = params.ReadString(config.Scheme, "") if scheme == "" && remotePortInt > 0 { scheme = utils.GetSchemeByPort(remotePortInt) } @@ -236,13 +214,13 @@ func (tc *TunnelController) resolveRemoteAddrAndScheme(params *options.Parameter remotePortInt = utils.GetPortByScheme(scheme) } - launchSSHStr := params.ReadString(LaunchSSH, "") + launchSSHStr := params.ReadString(config.LaunchSSH, "") if launchSSHStr != "" { if scheme == "" { scheme = utils.SSH } if scheme != utils.SSH { - err = fmt.Errorf("scheme %s is not compatible with the %s option", scheme, LaunchSSH) + err = fmt.Errorf("scheme %s is not compatible with the %s option", scheme, config.LaunchSSH) return } if remotePortInt == 0 { @@ -250,13 +228,13 @@ func (tc *TunnelController) resolveRemoteAddrAndScheme(params *options.Parameter } } - shouldLaunchRDP := params.ReadBool(LaunchRDP, false) + shouldLaunchRDP := params.ReadBool(config.LaunchRDP, false) if shouldLaunchRDP { if scheme == "" { scheme = utils.RDP } if scheme != utils.RDP { - err = fmt.Errorf("scheme %s is not compatible with the %s option", scheme, LaunchRDP) + err = fmt.Errorf("scheme %s is not compatible with the %s option", scheme, config.LaunchRDP) return } if remotePortInt == 0 { @@ -284,8 +262,8 @@ func (tc *TunnelController) launchHelperFlowIfNeeded( if launchSSHStr != "" { deleteTunnelParams := options.New(options.NewMapValuesProvider(map[string]interface{}{ - ClientID: clientID, - TunnelID: tunnelCreated.ID, + config.ClientID: clientID, + config.TunnelID: tunnelCreated.ID, })) return tc.startSSHFlow(ctx, tunnelCreated, params, deleteTunnelParams) } @@ -312,7 +290,7 @@ func (tc *TunnelController) startSSHFlow( tunnelCreated *models.TunnelCreated, params, deleteTunnelParams *options.ParameterBag, ) error { - sshParamsFlat := params.ReadString(LaunchSSH, "") + sshParamsFlat := params.ReadString(config.LaunchSSH, "") logrus.Debugf("ssh arguments are provided: '%s', will start an ssh session", sshParamsFlat) port, host, err := tc.extractPortAndHost(tunnelCreated, params) if err != nil { @@ -338,7 +316,7 @@ func (tc *TunnelController) startSSHFlow( } func (tc *TunnelController) generateUsage(tunnelCreated *models.TunnelCreated, params *options.ParameterBag) string { - shouldLaunchRDP := params.ReadBool(LaunchRDP, false) + shouldLaunchRDP := params.ReadBool(config.LaunchRDP, false) if !shouldLaunchRDP { port, host, err := tc.extractPortAndHost(tunnelCreated, params) @@ -401,9 +379,9 @@ func (tc *TunnelController) startRDPFlow( rdpFileInput := models.FileInput{ Address: fmt.Sprintf("%s:%s", host, port), - ScreenHeight: params.ReadInt(RDPHeight, 0), - ScreenWidth: params.ReadInt(RDPWidth, 0), - UserName: params.ReadString(RDPUser, ""), + ScreenHeight: params.ReadInt(config.RDPHeight, 0), + ScreenWidth: params.ReadInt(config.RDPWidth, 0), + UserName: params.ReadString(config.RDPUser, ""), FileName: fmt.Sprintf("%s.rdp", clientName), } diff --git a/internal/pkg/controllers/tunnel_test.go b/internal/pkg/controllers/tunnel_test.go index adcb5c5..7a2cd9b 100644 --- a/internal/pkg/controllers/tunnel_test.go +++ b/internal/pkg/controllers/tunnel_test.go @@ -170,10 +170,10 @@ func TestTunnelDeleteByClientIDController(t *testing.T) { assert.False(t, isSSHExecuted) params := options.New(options.NewMapValuesProvider(map[string]interface{}{ - ClientID: "cl1", - TunnelID: "tun2", + config.ClientID: "cl1", + config.TunnelID: "tun2", config.ClientNamesFlag: "", - ForceDeletion: "1", + config.ForceDeletion: "1", })) err := tController.Delete(context.Background(), params) assert.NoError(t, err) @@ -183,8 +183,8 @@ func TestTunnelDeleteByClientIDController(t *testing.T) { func TestInvalidInputForTunnelDelete(t *testing.T) { tController := TunnelController{} params := options.New(options.NewMapValuesProvider(map[string]interface{}{ - ClientID: "", - TunnelID: "tunnel11", + config.ClientID: "", + config.TunnelID: "tunnel11", config.ClientNamesFlag: "", })) err := tController.Delete(context.Background(), params) @@ -239,13 +239,13 @@ func TestTunnelCreateWithClientID(t *testing.T) { assert.False(t, isSSHExecuted) params := config.FromValues(map[string]string{ - ClientID: "334", - Local: "lohost1:3300", - Remote: "rhost2:3344", - Scheme: utils.SSH, - CheckPort: "1", - config.ServerURL: "https://localhost.com:34", - IdleTimeoutMinutes: "7", + config.ClientID: "334", + config.Local: "lohost1:3300", + config.Remote: "rhost2:3344", + config.Scheme: utils.SSH, + config.CheckPort: "1", + config.ServerURL: "https://localhost.com:34", + config.IdleTimeoutMinutes: "7", }) err := tController.Create(context.Background(), params) assert.NoError(t, err) @@ -260,12 +260,12 @@ func TestTunnelCreateWithClientID(t *testing.T) { func TestInvalidInputForTunnelCreate(t *testing.T) { tController := TunnelController{} params := config.FromValues(map[string]string{ - ClientID: "", + config.ClientID: "", config.ClientNamesFlag: "", - Local: "lohost1:3300", - Remote: "rhost2:3344", - Scheme: utils.SSH, - CheckPort: "1", + config.Local: "lohost1:3300", + config.Remote: "rhost2:3344", + config.Scheme: utils.SSH, + config.CheckPort: "1", }) err := tController.Create(context.Background(), params) assert.EqualError(t, err, "no client id nor name provided") @@ -310,9 +310,9 @@ func TestTunnelCreateWithSchemeDiscovery(t *testing.T) { } params := map[string]string{ - ClientID: "32312", - Local: "lohost33:3301", - Remote: "rhost5:22", + config.ClientID: "32312", + config.Local: "lohost33:3301", + config.Remote: "rhost5:22", config.ServerURL: "http://ya.ru", } err := tController.Create(context.Background(), config.FromValues(params)) @@ -371,9 +371,9 @@ func TestTunnelCreateWithPortDiscovery(t *testing.T) { } params := map[string]string{ - ClientID: "1313", - Local: "lohost44:3302", - Scheme: utils.SSH, + config.ClientID: "1313", + config.Local: "lohost44:3302", + config.Scheme: utils.SSH, config.ServerURL: "http://some.com", } err := tController.Create(context.Background(), config.FromValues(params)) @@ -391,8 +391,8 @@ func TestTunnelCreateWithPortDiscovery(t *testing.T) { ) buf = bytes.Buffer{} - delete(params, Scheme) - params[LaunchSSH] = "-l root" + delete(params, config.Scheme) + params[config.LaunchSSH] = "-l root" err = tController.Create(context.Background(), config.FromValues(params)) assert.NoError(t, err) @@ -458,12 +458,12 @@ func TestTunnelCreateWithSSH(t *testing.T) { } params := config.FromValues(map[string]string{ - ClientID: "1314", - Local: "lohost77:3303", - Scheme: utils.SSH, - config.ServerURL: "http://rport-url.com", - LaunchSSH: "-l root -i somefile", - IdleTimeoutMinutes: "5", + config.ClientID: "1314", + config.Local: "lohost77:3303", + config.Scheme: utils.SSH, + config.ServerURL: "http://rport-url.com", + config.LaunchSSH: "-l root -i somefile", + config.IdleTimeoutMinutes: "5", }) err := tController.Create(context.Background(), params) assert.NoError(t, err) @@ -528,10 +528,10 @@ func TestTunnelCreateWithSSHFailure(t *testing.T) { } params := config.FromValues(map[string]string{ - ClientID: "1316", - Local: "lohost776:3306", + config.ClientID: "1316", + config.Local: "lohost776:3306", config.ServerURL: "http://rport-url2.com", - LaunchSSH: "-l root", + config.LaunchSSH: "-l root", }) err := tController.Create(context.Background(), params) assert.EqualError(t, err, "ssh failure") @@ -583,15 +583,15 @@ func TestTunnelCreateWithRDP(t *testing.T) { } params := config.FromValues(map[string]string{ - ClientID: "1314", - Local: "lohost88:3304", - Scheme: utils.RDP, - config.ServerURL: "http://rport-url123.com", - LaunchRDP: "1", - RDPUser: "Administrator", - RDPWidth: "1090", - RDPHeight: "990", - IdleTimeoutMinutes: "5", + config.ClientID: "1314", + config.Local: "lohost88:3304", + config.Scheme: utils.RDP, + config.ServerURL: "http://rport-url123.com", + config.LaunchRDP: "1", + config.RDPUser: "Administrator", + config.RDPWidth: "1090", + config.RDPHeight: "990", + config.IdleTimeoutMinutes: "5", }) err := tController.Create(context.Background(), params) assert.NoError(t, err) @@ -636,15 +636,15 @@ func TestTunnelCreateWithRDPIncompatibleFlags(t *testing.T) { } params := config.FromValues(map[string]string{ - ClientID: "1319", - Local: "lohost88:3305", - Scheme: utils.RDP, + config.ClientID: "1319", + config.Local: "lohost88:3305", + config.Scheme: utils.RDP, config.ServerURL: "http://rport-url123.com", - LaunchSSH: "-l root", - ACL: "0.0.0.0", + config.LaunchSSH: "-l root", + config.ACL: "0.0.0.0", }) err := tController.Create(context.Background(), params) - assert.EqualError(t, err, fmt.Sprintf("scheme rdp is not compatible with the %s option", LaunchSSH)) + assert.EqualError(t, err, fmt.Sprintf("scheme rdp is not compatible with the %s option", config.LaunchSSH)) } func TestTunnelCreateWithSSHIncompatibleFlags(t *testing.T) { @@ -668,14 +668,14 @@ func TestTunnelCreateWithSSHIncompatibleFlags(t *testing.T) { } params := config.FromValues(map[string]string{ - ClientID: "1320", - Local: "lohost88:3309", - Scheme: utils.SSH, + config.ClientID: "1320", + config.Local: "lohost88:3309", + config.Scheme: utils.SSH, config.ServerURL: "http://rport-url125.com", - LaunchRDP: "1", + config.LaunchRDP: "1", }) err := tController.Create(context.Background(), params) - assert.EqualError(t, err, fmt.Sprintf("scheme ssh is not compatible with the %s option", LaunchRDP)) + assert.EqualError(t, err, fmt.Sprintf("scheme ssh is not compatible with the %s option", config.LaunchRDP)) assert.False(t, isSSHCalled) } @@ -715,8 +715,8 @@ func TestTunnelDeleteFailureWithActiveConnections(t *testing.T) { }, } params := options.New(options.NewMapValuesProvider(map[string]interface{}{ - ClientID: "cl1", - TunnelID: "tun2", + config.ClientID: "cl1", + config.TunnelID: "tun2", })) err := tController.Delete(context.Background(), params) assert.EqualError(t, err, "tunnel is still active: it has 1 active connection(s), code: 123, details: , use -f to delete it anyway")