Skip to content

Commit 958b6f1

Browse files
committed
TUN-7813: Improve tunnel delete command to use cascade delete
## Summary Previously the force flag in the tunnel delete command was only explicitly deleting the connections of a tunnel. Therefore, we are changing it to use the cascade query parameter supported by the API. That parameter will delegate to the server the deletion of the tunnel dependencies implicitly instead of the client doing it explicitly. This means that not only the connections will get deleted, but also the tunnel routes, ensuring that no dependencies are left without a non-deleted tunnel.
1 parent 6d1d91d commit 958b6f1

File tree

5 files changed

+12
-12
lines changed

5 files changed

+12
-12
lines changed

cfapi/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ type TunnelClient interface {
99
GetTunnel(tunnelID uuid.UUID) (*Tunnel, error)
1010
GetTunnelToken(tunnelID uuid.UUID) (string, error)
1111
GetManagementToken(tunnelID uuid.UUID) (string, error)
12-
DeleteTunnel(tunnelID uuid.UUID) error
12+
DeleteTunnel(tunnelID uuid.UUID, cascade bool) error
1313
ListTunnels(filter *TunnelFilter) ([]*Tunnel, error)
1414
ListActiveClients(tunnelID uuid.UUID) ([]*ActiveClient, error)
1515
CleanupConnections(tunnelID uuid.UUID, params *CleanupParams) error

cfapi/tunnel.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,14 @@ func (r *RESTClient) GetManagementToken(tunnelID uuid.UUID) (token string, err e
159159
return "", r.statusCodeToError("get tunnel token", resp)
160160
}
161161

162-
func (r *RESTClient) DeleteTunnel(tunnelID uuid.UUID) error {
162+
func (r *RESTClient) DeleteTunnel(tunnelID uuid.UUID, cascade bool) error {
163163
endpoint := r.baseEndpoints.accountLevel
164164
endpoint.Path = path.Join(endpoint.Path, fmt.Sprintf("%v", tunnelID))
165+
// Cascade will delete all tunnel dependencies (connections, routes, etc.) that
166+
// are linked to the deleted tunnel.
167+
if cascade {
168+
endpoint.RawQuery = "cascade=true"
169+
}
165170
resp, err := r.sendRequest("DELETE", endpoint, nil)
166171
if err != nil {
167172
return errors.Wrap(err, "REST request failed")

cmd/cloudflared/tunnel/subcommand_context.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ func (sc *subcommandContext) create(name string, credentialsFilePath string, sec
156156
var errorLines []string
157157
errorLines = append(errorLines, fmt.Sprintf("Your tunnel '%v' was created with ID %v. However, cloudflared couldn't write tunnel credentials to %s.", tunnel.Name, tunnel.ID, credentialsFilePath))
158158
errorLines = append(errorLines, fmt.Sprintf("The file-writing error is: %v", writeFileErr))
159-
if deleteErr := client.DeleteTunnel(tunnel.ID); deleteErr != nil {
159+
if deleteErr := client.DeleteTunnel(tunnel.ID, true); deleteErr != nil {
160160
errorLines = append(errorLines, fmt.Sprintf("Cloudflared tried to delete the tunnel for you, but encountered an error. You should use `cloudflared tunnel delete %v` to delete the tunnel yourself, because the tunnel can't be run without the tunnelfile.", tunnel.ID))
161161
errorLines = append(errorLines, fmt.Sprintf("The delete tunnel error is: %v", deleteErr))
162162
} else {
@@ -206,13 +206,8 @@ func (sc *subcommandContext) delete(tunnelIDs []uuid.UUID) error {
206206
if !tunnel.DeletedAt.IsZero() {
207207
return fmt.Errorf("Tunnel %s has already been deleted", tunnel.ID)
208208
}
209-
if forceFlagSet {
210-
if err := client.CleanupConnections(tunnel.ID, cfapi.NewCleanupParams()); err != nil {
211-
return errors.Wrapf(err, "Error cleaning up connections for tunnel %s", tunnel.ID)
212-
}
213-
}
214209

215-
if err := client.DeleteTunnel(tunnel.ID); err != nil {
210+
if err := client.DeleteTunnel(tunnel.ID, forceFlagSet); err != nil {
216211
return errors.Wrapf(err, "Error deleting tunnel %s", tunnel.ID)
217212
}
218213

cmd/cloudflared/tunnel/subcommand_context_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ func (d *deleteMockTunnelStore) GetTunnelToken(tunnelID uuid.UUID) (string, erro
219219
return "token", nil
220220
}
221221

222-
func (d *deleteMockTunnelStore) DeleteTunnel(tunnelID uuid.UUID) error {
222+
func (d *deleteMockTunnelStore) DeleteTunnel(tunnelID uuid.UUID, cascade bool) error {
223223
tunnel, ok := d.mockTunnels[tunnelID]
224224
if !ok {
225225
return fmt.Errorf("Couldn't find tunnel: %v", tunnelID)

cmd/cloudflared/tunnel/subcommands.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ var (
119119
forceDeleteFlag = &cli.BoolFlag{
120120
Name: "force",
121121
Aliases: []string{"f"},
122-
Usage: "Cleans up any stale connections before the tunnel is deleted. cloudflared will not " +
123-
"delete a tunnel with connections without this flag.",
122+
Usage: "Deletes a tunnel even if tunnel is connected and it has dependencies associated to it. (eg. IP routes)." +
123+
" It is not possible to delete tunnels that have connections or non-deleted dependencies, without this flag.",
124124
EnvVars: []string{"TUNNEL_RUN_FORCE_OVERWRITE"},
125125
}
126126
selectProtocolFlag = altsrc.NewStringFlag(&cli.StringFlag{

0 commit comments

Comments
 (0)