From 3d782f7162f5c41b34898d5de24fb02d6785efd9 Mon Sep 17 00:00:00 2001 From: Rachel Williams Date: Fri, 10 Jul 2020 15:11:31 -0700 Subject: [PATCH] TUN-3048: Handle error when user tries to delete active tunnel --- cmd/cloudflared/tunnel/subcommands.go | 29 ++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/cmd/cloudflared/tunnel/subcommands.go b/cmd/cloudflared/tunnel/subcommands.go index 09f176a6..75bbac31 100644 --- a/cmd/cloudflared/tunnel/subcommands.go +++ b/cmd/cloudflared/tunnel/subcommands.go @@ -55,6 +55,11 @@ var ( Aliases: []string{credFileFlagAlias}, Usage: "File path of tunnel credentials", } + forceDeleteFlag = &cli.BoolFlag{ + Name: "force", + Aliases: []string{"f"}, + Usage: "Allows you to delete a tunnel, even if it has active connections.", + } ) const hideSubcommands = true @@ -309,7 +314,7 @@ func buildDeleteCommand() *cli.Command { Usage: "Delete existing tunnel with given ID", ArgsUsage: "TUNNEL-ID", Hidden: hideSubcommands, - Flags: []cli.Flag{credentialsFileFlag}, + Flags: []cli.Flag{credentialsFileFlag, forceDeleteFlag}, } } @@ -330,6 +335,28 @@ func deleteTunnel(c *cli.Context) error { } client := newTunnelstoreClient(c, cert, logger) + forceFlagSet := c.Bool("force") + + tunnel, err := client.GetTunnel(id) + if err != nil { + return errors.Wrapf(err, "Can't get tunnel information. Please check tunnel id: %s", id) + } + + // Check if tunnel DeletedAt field has already been set + if !tunnel.DeletedAt.IsZero() { + return errors.New("This tunnel has already been deleted.") + } + // Check if tunnel has existing connections and if force flag is set, cleanup connections + if len(tunnel.Connections) > 0 { + if !forceFlagSet { + return errors.New("You can not delete this tunnel because it has active connections. To see connections run the 'list' command. If you believe the tunnel is not active, you can use a -f / --force flag with this command.") + } + + if err := client.CleanupConnections(id); err != nil { + return errors.Wrapf(err, "Error cleaning up connections for tunnel %s", id) + } + } + if err := client.DeleteTunnel(id); err != nil { return errors.Wrapf(err, "Error deleting tunnel %s", id) }