-
Notifications
You must be signed in to change notification settings - Fork 0
/
update.go
86 lines (72 loc) · 2.12 KB
/
update.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// +build windows
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/gentlemanautomaton/globber"
"github.com/gentlemanautomaton/winservice"
"github.com/jackpal/gateway"
"gopkg.in/alecthomas/kingpin.v2"
)
// UpdateCommand returns an update command and configuration for app.
func UpdateCommand(app *kingpin.Application) (*kingpin.CmdClause, *UpdateConfig) {
cmd := app.Command("update", "Updates the requested tunnel state as necessary.")
conf := &UpdateConfig{}
conf.Bind(cmd)
return cmd, conf
}
// UpdateConfig holds configuration for the update command.
type UpdateConfig struct {
Tunnel string
Gateways []string
}
// Bind binds the update configuration to the command.
func (conf *UpdateConfig) Bind(cmd *kingpin.CmdClause) {
cmd.Flag("tunnel", "WireGuard tunnel name to toggle").Short('t').Required().StringVar(&conf.Tunnel)
cmd.Flag("gateway", "Gateway IP addresses match").Short('g').Required().StringsVar(&conf.Gateways)
}
func update(ctx context.Context, conf UpdateConfig) {
tunnel := "WireGuardTunnel$" + conf.Tunnel
svcFound, err := winservice.Exists(tunnel)
if err != nil {
fmt.Printf("Service check failed: %v.\n", err)
os.Exit(2)
}
if !svcFound {
// The WireGuard tunnel service doesn't exist. There's nothing to
// manage so we just exit.
return
}
fmt.Printf("Tunnel found: %s\n", tunnel)
gw, err := gateway.DiscoverGateway()
if err != nil {
fmt.Printf("Gateway query failed: %s\n", tunnel)
}
fmt.Printf("Gateway discovered: %s\n", gw)
gateways := globber.NewSet(conf.Gateways...)
matched := gateways.Match(gw.String())
if matched {
fmt.Printf("Gateway matched: %s\n", gw)
} else {
fmt.Printf("Gateway not matched.\n")
}
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
if !matched {
fmt.Printf("Starting %s...", tunnel)
if err := winservice.Start(ctx, tunnel); err != nil {
fmt.Printf(" failed: %v\n", err)
os.Exit(3)
}
fmt.Printf(" succeeded.")
} else {
fmt.Printf("Stopping %s...", tunnel)
if err := winservice.Stop(ctx, tunnel); err != nil {
fmt.Printf(" failed: %v\n", err)
os.Exit(3)
}
fmt.Printf(" succeeded.")
}
}