Skip to content

Commit

Permalink
Force tunnel deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
breathbath committed Apr 14, 2021
1 parent 8abf4a4 commit 05fbbd8
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 16 deletions.
7 changes: 7 additions & 0 deletions cmd/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,13 @@ func getDeleteTunnelRequirements() []config.ParameterRequirement {
Description: `client name, if no client id is provided`,
ShortName: "n",
},
{
Field: controllers.ForceDeletion,
ShortName: "f",
Default: "0",
Description: `force tunnel deletion if it has active connections`,
Type: config.BoolRequirementType,
},
{
Field: controllers.TunnelID,
Description: "[required] tunnel id to delete",
Expand Down
7 changes: 6 additions & 1 deletion internal/pkg/api/tunnels.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (rp *Rport) CreateTunnel(
return tunResp, err
}

func (rp *Rport) DeleteTunnel(ctx context.Context, clientID, tunnelID string) (err error) {
func (rp *Rport) DeleteTunnel(ctx context.Context, clientID, tunnelID string, force bool) (err error) {
var req *http.Request
u := strings.Replace(TunnelsURL, "{client_id}", clientID, 1)
u = strings.Replace(u, "{tunnel_id}", tunnelID, 1)
Expand All @@ -67,6 +67,11 @@ func (rp *Rport) DeleteTunnel(ctx context.Context, clientID, tunnelID string) (e
if err != nil {
return
}
if force {
q := req.URL.Query()
q.Add("force", "1")
req.URL.RawQuery = q.Encode()
}

resp, err := rp.CallBaseClient(req, nil)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions internal/pkg/api/tunnels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func TestDeleteTunnel(t *testing.T) {
context.Background(),
"123",
"345",
false,
)
assert.NoError(t, err)
if err != nil {
Expand Down
32 changes: 18 additions & 14 deletions internal/pkg/controllers/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,20 @@ import (
)

const (
ClientID = "client"
TunnelID = "tunnel"
Local = "local"
Remote = "remote"
Scheme = "scheme"
ACL = "acl"
CheckPort = "checkp"
LaunchSSH = "launch-ssh"
LaunchRDP = "launch-rdp"
RDPWidth = "rdp-width"
RDPHeight = "rdp-height"
RDPUser = "rdp-user"
DefaultACL = "<<YOU CURRENT PUBLIC IP>>"
ClientID = "client"
TunnelID = "tunnel"
Local = "local"
Remote = "remote"
Scheme = "scheme"
ACL = "acl"
CheckPort = "checkp"
LaunchSSH = "launch-ssh"
LaunchRDP = "launch-rdp"
RDPWidth = "rdp-width"
RDPHeight = "rdp-height"
RDPUser = "rdp-user"
DefaultACL = "<<YOU CURRENT PUBLIC IP>>"
ForceDeletion = "force"
)

type TunnelRenderer interface {
Expand Down Expand Up @@ -107,8 +108,11 @@ func (tc *TunnelController) Delete(ctx context.Context, params *options.Paramete
clientID = clients[0].ID
}

err := tc.Rport.DeleteTunnel(ctx, clientID, tunnelID)
err := tc.Rport.DeleteTunnel(ctx, clientID, tunnelID, params.ReadBool(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)
}
return err
}

Expand Down
48 changes: 47 additions & 1 deletion internal/pkg/controllers/tunnel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func TestTunnelDeleteByClientIDController(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
assert.Equal(t, "Basic bG9nMTU1OnBhc3MxNTU=", r.Header.Get("Authorization"))
assert.Equal(t, http.MethodDelete, r.Method)
assert.Equal(t, "/api/v1/clients/cl1/tunnels/tun2", r.URL.String())
assert.Equal(t, "/api/v1/clients/cl1/tunnels/tun2?force=1", r.URL.String())
rw.WriteHeader(http.StatusNoContent)
}))
defer srv.Close()
Expand Down Expand Up @@ -164,6 +164,7 @@ func TestTunnelDeleteByClientIDController(t *testing.T) {
ClientID: "cl1",
TunnelID: "tun2",
ClientNameFlag: "",
ForceDeletion: "1",
}))
err := tController.Delete(context.Background(), params)
assert.NoError(t, err)
Expand Down Expand Up @@ -803,6 +804,7 @@ func TestTunnelCreateWithRDPIncompatibleFlags(t *testing.T) {
RDPWriter: nil,
RDPExecutor: &rdp.Executor{
CommandProvider: func(filePath string) (cmd string, args []string) {
isRDPCalled = true
return
},
StdOut: &cmdOutput,
Expand Down Expand Up @@ -854,3 +856,47 @@ func TestTunnelCreateWithSSHIncompatibleFlags(t *testing.T) {
assert.EqualError(t, err, fmt.Sprintf("scheme ssh is not compatible with the %s option", LaunchRDP))
assert.False(t, isSSHCalled)
}

func TestTunnelDeleteFailureWithActiveConnections(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.WriteHeader(http.StatusInternalServerError)
assert.Equal(t, http.MethodDelete, r.Method)
errs := models.ErrorResp{
Errors: []models.Error{
{
Code: "123",
Title: "tunnel is still active: it has 1 active connection(s)",
},
},
}
jsonEnc := json.NewEncoder(rw)
e := jsonEnc.Encode(errs)
assert.NoError(t, e)
}))
defer srv.Close()

apiAuth := &utils.StorageBasicAuth{
AuthProvider: func() (login, pass string, err error) {
login = "342314"
pass = "gfgdgafd"
return
},
}
cl := api.New(srv.URL, apiAuth)
buf := bytes.Buffer{}

tController := TunnelController{
Rport: cl,
TunnelRenderer: &TunnelRendererMock{Writer: &buf},
ClientSearch: &ClientSearchMock{},
SSHFunc: func(sshParams []string) error {
return nil
},
}
params := options.New(options.NewMapValuesProvider(map[string]interface{}{
ClientID: "cl1",
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")
}

0 comments on commit 05fbbd8

Please sign in to comment.