TUN-3998: Allow to cleanup the connections of a tunnel limited to a single client
This commit is contained in:
parent
9767ba1853
commit
4a7763e497
|
@ -224,7 +224,7 @@ func (sc *subcommandContext) delete(tunnelIDs []uuid.UUID) error {
|
||||||
return fmt.Errorf("Tunnel %s has already been deleted", tunnel.ID)
|
return fmt.Errorf("Tunnel %s has already been deleted", tunnel.ID)
|
||||||
}
|
}
|
||||||
if forceFlagSet {
|
if forceFlagSet {
|
||||||
if err := client.CleanupConnections(tunnel.ID); err != nil {
|
if err := client.CleanupConnections(tunnel.ID, tunnelstore.NewCleanupParams()); err != nil {
|
||||||
return errors.Wrapf(err, "Error cleaning up connections for tunnel %s", tunnel.ID)
|
return errors.Wrapf(err, "Error cleaning up connections for tunnel %s", tunnel.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,13 +276,24 @@ func (sc *subcommandContext) run(tunnelID uuid.UUID) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *subcommandContext) cleanupConnections(tunnelIDs []uuid.UUID) error {
|
func (sc *subcommandContext) cleanupConnections(tunnelIDs []uuid.UUID) error {
|
||||||
|
params := tunnelstore.NewCleanupParams()
|
||||||
|
extraLog := ""
|
||||||
|
if connector := sc.c.String("connector-id"); connector != "" {
|
||||||
|
connectorID, err := uuid.Parse(connector)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "%s is not a valid client ID (must be a UUID)", connector)
|
||||||
|
}
|
||||||
|
params.ForClient(connectorID)
|
||||||
|
extraLog = fmt.Sprintf(" for connector-id %s", connectorID.String())
|
||||||
|
}
|
||||||
|
|
||||||
client, err := sc.client()
|
client, err := sc.client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, tunnelID := range tunnelIDs {
|
for _, tunnelID := range tunnelIDs {
|
||||||
sc.log.Info().Msgf("Cleanup connection for tunnel %s", tunnelID)
|
sc.log.Info().Msgf("Cleanup connection for tunnel %s%s", tunnelID, extraLog)
|
||||||
if err := client.CleanupConnections(tunnelID); err != nil {
|
if err := client.CleanupConnections(tunnelID, params); err != nil {
|
||||||
sc.log.Error().Msgf("Error cleaning up connections for tunnel %v, error :%v", tunnelID, err)
|
sc.log.Error().Msgf("Error cleaning up connections for tunnel %v, error :%v", tunnelID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,12 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/rs/zerolog"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
|
|
||||||
"github.com/cloudflare/cloudflared/connection"
|
"github.com/cloudflare/cloudflared/connection"
|
||||||
"github.com/cloudflare/cloudflared/tunnelstore"
|
"github.com/cloudflare/cloudflared/tunnelstore"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
@ -260,7 +261,7 @@ func (d *deleteMockTunnelStore) DeleteTunnel(tunnelID uuid.UUID) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *deleteMockTunnelStore) CleanupConnections(tunnelID uuid.UUID) error {
|
func (d *deleteMockTunnelStore) CleanupConnections(tunnelID uuid.UUID, _ *tunnelstore.CleanupParams) error {
|
||||||
tunnel, ok := d.mockTunnels[tunnelID]
|
tunnel, ok := d.mockTunnels[tunnelID]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Couldn't find tunnel: %v", tunnelID)
|
return fmt.Errorf("Couldn't find tunnel: %v", tunnelID)
|
||||||
|
|
|
@ -126,6 +126,12 @@ var (
|
||||||
Usage: "Inverts the sort order of the tunnel info.",
|
Usage: "Inverts the sort order of the tunnel info.",
|
||||||
EnvVars: []string{"TUNNEL_INFO_INVERT_SORT"},
|
EnvVars: []string{"TUNNEL_INFO_INVERT_SORT"},
|
||||||
}
|
}
|
||||||
|
cleanupClientFlag = &cli.StringFlag{
|
||||||
|
Name: "connector-id",
|
||||||
|
Aliases: []string{"c"},
|
||||||
|
Usage: `Constraints the cleanup to stop the connections of a single Connector (by its ID). You can find the various Connectors (and their IDs) currently connected to your tunnel via 'cloudflared tunnel info <name>'.`,
|
||||||
|
EnvVars: []string{"TUNNEL_CLEANUP_CONNECTOR"},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func buildCreateCommand() *cli.Command {
|
func buildCreateCommand() *cli.Command {
|
||||||
|
@ -600,6 +606,7 @@ func buildCleanupCommand() *cli.Command {
|
||||||
Usage: "Cleanup tunnel connections",
|
Usage: "Cleanup tunnel connections",
|
||||||
UsageText: "cloudflared tunnel [tunnel command options] cleanup [subcommand options] TUNNEL",
|
UsageText: "cloudflared tunnel [tunnel command options] cleanup [subcommand options] TUNNEL",
|
||||||
Description: "Delete connections for tunnels with the given UUIDs or names.",
|
Description: "Delete connections for tunnels with the given UUIDs or names.",
|
||||||
|
Flags: []cli.Flag{cleanupClientFlag},
|
||||||
CustomHelpTemplate: commandHelpTemplate(),
|
CustomHelpTemplate: commandHelpTemplate(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package tunnelstore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CleanupParams struct {
|
||||||
|
queryParams url.Values
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCleanupParams() *CleanupParams {
|
||||||
|
return &CleanupParams{
|
||||||
|
queryParams: url.Values{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cp *CleanupParams) ForClient(clientID uuid.UUID) {
|
||||||
|
cp.queryParams.Set("client_id", clientID.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cp CleanupParams) encode() string {
|
||||||
|
return cp.queryParams.Encode()
|
||||||
|
}
|
|
@ -204,7 +204,7 @@ type Client interface {
|
||||||
DeleteTunnel(tunnelID uuid.UUID) error
|
DeleteTunnel(tunnelID uuid.UUID) error
|
||||||
ListTunnels(filter *Filter) ([]*Tunnel, error)
|
ListTunnels(filter *Filter) ([]*Tunnel, error)
|
||||||
ListActiveClients(tunnelID uuid.UUID) ([]*ActiveClient, error)
|
ListActiveClients(tunnelID uuid.UUID) ([]*ActiveClient, error)
|
||||||
CleanupConnections(tunnelID uuid.UUID) error
|
CleanupConnections(tunnelID uuid.UUID, params *CleanupParams) error
|
||||||
RouteTunnel(tunnelID uuid.UUID, route Route) (RouteResult, error)
|
RouteTunnel(tunnelID uuid.UUID, route Route) (RouteResult, error)
|
||||||
|
|
||||||
// Teamnet endpoints
|
// Teamnet endpoints
|
||||||
|
@ -370,8 +370,9 @@ func parseConnectionsDetails(reader io.Reader) ([]*ActiveClient, error) {
|
||||||
return clients, err
|
return clients, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RESTClient) CleanupConnections(tunnelID uuid.UUID) error {
|
func (r *RESTClient) CleanupConnections(tunnelID uuid.UUID, params *CleanupParams) error {
|
||||||
endpoint := r.baseEndpoints.accountLevel
|
endpoint := r.baseEndpoints.accountLevel
|
||||||
|
endpoint.RawQuery = params.encode()
|
||||||
endpoint.Path = path.Join(endpoint.Path, fmt.Sprintf("%v/connections", tunnelID))
|
endpoint.Path = path.Join(endpoint.Path, fmt.Sprintf("%v/connections", tunnelID))
|
||||||
resp, err := r.sendRequest("DELETE", endpoint, nil)
|
resp, err := r.sendRequest("DELETE", endpoint, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue