Skip to content

Commit

Permalink
flyctl wireguard reset
Browse files Browse the repository at this point in the history
every once in awhile people get peers in weird states, and while i
think we've caught most of the problems here, it sucks to have to
edit ~/.fly/config.yaml to clear out bad state, so now there's a
command for it.
  • Loading branch information
tqbf committed Feb 17, 2022
1 parent e91d4b1 commit 06063f0
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 18 deletions.
25 changes: 24 additions & 1 deletion cmd/wireguard.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmd

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
Expand All @@ -19,6 +20,7 @@ import (
"github.com/superfly/flyctl/docstrings"
"github.com/superfly/flyctl/internal/client"
"github.com/superfly/flyctl/internal/wireguard"
"github.com/superfly/flyctl/pkg/agent"
)

func newWireGuardCommand(client *client.Client) *Command {
Expand All @@ -33,6 +35,7 @@ func newWireGuardCommand(client *client.Client) *Command {
child(cmd, runWireGuardCreate, "wireguard.create").Args = cobra.MaximumNArgs(4)
child(cmd, runWireGuardRemove, "wireguard.remove").Args = cobra.MaximumNArgs(2)
child(cmd, runWireGuardStat, "wireguard.status").Args = cobra.MaximumNArgs(2)
child(cmd, runWireGuardResetPeer, "wireguard.reset").Args = cobra.MaximumNArgs(1)

tokens := child(cmd, nil, "wireguard.token")

Expand Down Expand Up @@ -193,8 +196,28 @@ func resolveOutputWriter(ctx *cmdctx.CmdContext, idx int, prompt string) (w io.W
}
}

func runWireGuardCreate(ctx *cmdctx.CmdContext) error {
func runWireGuardResetPeer(ctx *cmdctx.CmdContext) error {
org, err := orgByArg(ctx)
if err != nil {
return err
}

client := ctx.Client.API()
agentclient, err := agent.Establish(context.Background(), client)
if err != nil {
return err
}

conf, err := agentclient.Reestablish(context.Background(), org.Slug)
if err != nil {
return err
}

fmt.Printf("New WireGuard peer for organization '%s': '%s'\n", org.Slug, conf.WireGuardState.Name)
return nil
}

func runWireGuardCreate(ctx *cmdctx.CmdContext) error {
org, err := orgByArg(ctx)
if err != nil {
return err
Expand Down
4 changes: 4 additions & 0 deletions docstrings/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,10 @@ number to operate. This can be found through the volumes list command`,
return KeyStrings{"remove [org] [name]", "Remove a WireGuard peer connection",
`Remove a WireGuard peer connection from an organization`,
}
case "wireguard.reset":
return KeyStrings{"reset [org]", "Reset WireGuard peer connection for an organization",
`Reset WireGuard peer connection for an organization`,
}
case "wireguard.status":
return KeyStrings{"status [org] [name]", "Get status a WireGuard peer connection",
`Get status for a WireGuard peer connection`,
Expand Down
5 changes: 5 additions & 0 deletions helpgen/flyctlhelp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,11 @@ longHelp = """Add a WireGuard peer connection to an organization"""
shortHelp = "Add a WireGuard peer connection"
usage = "create [org] [region] [name]"

[wireguard.reset]
longHelp = """Reset WireGuard peer connection for an organization"""
shortHelp = "Reset WireGuard peer connection for an organization"
usage = "reset [org]"

[wireguard.remove]
longHelp = """Remove a WireGuard peer connection from an organization"""
shortHelp = "Remove a WireGuard peer connection"
Expand Down
4 changes: 2 additions & 2 deletions internal/wireguard/wg.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ var (
cleanDNSPattern = regexp.MustCompile(`[^a-zA-Z0-9\\-]`)
)

func StateForOrg(apiClient *api.Client, org *api.Organization, regionCode string, name string) (*wg.WireGuardState, error) {
func StateForOrg(apiClient *api.Client, org *api.Organization, regionCode, name string, recycle bool) (*wg.WireGuardState, error) {
state, err := getWireGuardStateForOrg(org.Slug)
if err != nil {
return nil, err
}
if state != nil {
if state != nil && !recycle {
return state, nil
}

Expand Down
17 changes: 15 additions & 2 deletions pkg/agent/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,14 @@ type EstablishResponse struct {
TunnelConfig *wg.Config
}

func (c *Client) Establish(ctx context.Context, slug string) (res *EstablishResponse, err error) {
func (c *Client) doEstablish(ctx context.Context, slug string, recycle bool) (res *EstablishResponse, err error) {
err = c.do(ctx, func(conn net.Conn) (err error) {
if err = proto.Write(conn, "establish", slug); err != nil {
verb := "establish"
if recycle {
verb = "reestablish"
}

if err = proto.Write(conn, verb, slug); err != nil {
return
}

Expand Down Expand Up @@ -263,6 +268,14 @@ func (c *Client) Establish(ctx context.Context, slug string) (res *EstablishResp
return
}

func (c *Client) Establish(ctx context.Context, slug string) (res *EstablishResponse, err error) {
return c.doEstablish(ctx, slug, false)
}

func (c *Client) Reestablish(ctx context.Context, slug string) (res *EstablishResponse, err error) {
return c.doEstablish(ctx, slug, true)
}

func (c *Client) Probe(ctx context.Context, slug string) error {
return c.do(ctx, func(conn net.Conn) (err error) {
if err = proto.Write(conn, "probe", slug); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions pkg/agent/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,17 +201,17 @@ func (s *server) checkForConfigChange() (err error) {
return
}

func (s *server) buildTunnel(org *api.Organization) (tunnel *wg.Tunnel, err error) {
func (s *server) buildTunnel(org *api.Organization, recycle bool) (tunnel *wg.Tunnel, err error) {
s.mu.Lock()
defer s.mu.Unlock()

if tunnel = s.tunnels[org.Slug]; tunnel != nil {
if tunnel = s.tunnels[org.Slug]; tunnel != nil && !recycle {
// tunnel already exists
return
}

var state *wg.WireGuardState
if state, err = wireguard.StateForOrg(s.Client, org, "", ""); err != nil {
if state, err = wireguard.StateForOrg(s.Client, org, "", "", recycle); err != nil {
return
}

Expand Down
29 changes: 19 additions & 10 deletions pkg/agent/server/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,15 @@ func runSession(ctx context.Context, srv *server, conn net.Conn, id id) {
type handlerFunc func(*session, context.Context, ...string)

var handlers = map[string]handlerFunc{
"kill": (*session).kill,
"ping": (*session).ping,
"establish": (*session).establish,
"connect": (*session).connect,
"probe": (*session).probe,
"instances": (*session).instances,
"resolve": (*session).resolve,
"ping6": (*session).ping6,
"kill": (*session).kill,
"ping": (*session).ping,
"establish": (*session).establish,
"reestablish": (*session).reestablish,
"connect": (*session).connect,
"probe": (*session).probe,
"instances": (*session).instances,
"resolve": (*session).resolve,
"ping6": (*session).ping6,
}

var errMalformedKill = errors.New("malformed kill command")
Expand Down Expand Up @@ -147,7 +148,7 @@ var (
errMalformedEstablish = errors.New("malformed establish command")
)

func (s *session) establish(ctx context.Context, args ...string) {
func (s *session) doEstablish(ctx context.Context, recycle bool, args ...string) {
if !s.exactArgs(1, args, errMalformedEstablish) {
return
}
Expand All @@ -159,7 +160,7 @@ func (s *session) establish(ctx context.Context, args ...string) {
return
}

tunnel, err := s.srv.buildTunnel(org)
tunnel, err := s.srv.buildTunnel(org, recycle)
if err != nil {
s.error(err)

Expand All @@ -172,6 +173,14 @@ func (s *session) establish(ctx context.Context, args ...string) {
})
}

func (s *session) establish(ctx context.Context, args ...string) {
s.doEstablish(ctx, false, args...)
}

func (s *session) reestablish(ctx context.Context, args ...string) {
s.doEstablish(ctx, true, args...)
}

var errNoSuchOrg = errors.New("no such organization")

func (s *session) fetchOrg(ctx context.Context, slug string) (*api.Organization, error) {
Expand Down

0 comments on commit 06063f0

Please sign in to comment.