mirror of
https://github.com/netbirdio/netbird.git
synced 2025-02-23 05:31:28 +01:00
add wiretrustee LOGIN command (#90)
* feature: add wiretrustee LOGIN command * chore: add management initial connection timeout * test: add login cmd test * test: validate generated config in login cmd * test: add up command test * chore: add timeout to signal client creation method * test: close wireguard interface once test finished
This commit is contained in:
parent
f7e51e7453
commit
1dfa99d07c
152
client/cmd/login.go
Normal file
152
client/cmd/login.go
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/wiretrustee/wiretrustee/client/internal"
|
||||||
|
mgm "github.com/wiretrustee/wiretrustee/management/client"
|
||||||
|
mgmProto "github.com/wiretrustee/wiretrustee/management/proto"
|
||||||
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
setupKey string
|
||||||
|
|
||||||
|
loginCmd = &cobra.Command{
|
||||||
|
Use: "login",
|
||||||
|
Short: "login to the Wiretrustee Management Service (first run)",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
InitLog(logLevel)
|
||||||
|
|
||||||
|
config, err := internal.GetConfig(managementURL, configPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed getting config %s %v", configPath, err)
|
||||||
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//validate our peer's Wireguard PRIVATE key
|
||||||
|
myPrivateKey, err := wgtypes.ParseKey(config.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed parsing Wireguard key %s: [%s]", config.PrivateKey, err.Error())
|
||||||
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
mgmTlsEnabled := false
|
||||||
|
if config.ManagementURL.Scheme == "https" {
|
||||||
|
mgmTlsEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("connecting to Management Service %s", config.ManagementURL.String())
|
||||||
|
mgmClient, err := mgm.NewClient(ctx, config.ManagementURL.Host, myPrivateKey, mgmTlsEnabled)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed connecting to Management Service %s %v", config.ManagementURL.String(), err)
|
||||||
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debugf("connected to anagement Service %s", config.ManagementURL.String())
|
||||||
|
|
||||||
|
serverKey, err := mgmClient.GetServerPublicKey()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed while getting Management Service public key: %v", err)
|
||||||
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = loginPeer(*serverKey, mgmClient, setupKey)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed logging-in peer on Management Service : %v", err)
|
||||||
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = mgmClient.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed closing Management Service client: %v", err)
|
||||||
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// loginPeer attempts to login to Management Service. If peer wasn't registered, tries the registration flow.
|
||||||
|
func loginPeer(serverPublicKey wgtypes.Key, client *mgm.Client, setupKey string) (*mgmProto.LoginResponse, error) {
|
||||||
|
|
||||||
|
loginResp, err := client.Login(serverPublicKey)
|
||||||
|
if err != nil {
|
||||||
|
if s, ok := status.FromError(err); ok && s.Code() == codes.PermissionDenied {
|
||||||
|
log.Debugf("peer registration required")
|
||||||
|
return registerPeer(serverPublicKey, client, setupKey)
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("peer has successfully logged-in to Management Service")
|
||||||
|
|
||||||
|
return loginResp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// registerPeer checks whether setupKey was provided via cmd line and if not then it prompts user to enter a key.
|
||||||
|
// Otherwise tries to register with the provided setupKey via command line.
|
||||||
|
func registerPeer(serverPublicKey wgtypes.Key, client *mgm.Client, setupKey string) (*mgmProto.LoginResponse, error) {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
if setupKey == "" {
|
||||||
|
setupKey, err = promptPeerSetupKey()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed getting setup key from user: %s", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
validSetupKey, err := uuid.Parse(setupKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("sending peer registration request to Management Service")
|
||||||
|
loginResp, err := client.Register(serverPublicKey, validSetupKey.String())
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed registering peer %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("peer has been successfully registered on Management Service")
|
||||||
|
|
||||||
|
return loginResp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// promptPeerSetupKey prompts user to enter Setup Key
|
||||||
|
func promptPeerSetupKey() (string, error) {
|
||||||
|
fmt.Print("Enter setup key: ")
|
||||||
|
|
||||||
|
s := bufio.NewScanner(os.Stdin)
|
||||||
|
for s.Scan() {
|
||||||
|
input := s.Text()
|
||||||
|
if input != "" {
|
||||||
|
return input, nil
|
||||||
|
}
|
||||||
|
fmt.Println("Specified key is empty, try again:")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", s.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
loginCmd.PersistentFlags().StringVar(&setupKey, "setup-key", "", "Setup key obtained from the Management Service Dashboard (used to register peer)")
|
||||||
|
}
|
68
client/cmd/login_test.go
Normal file
68
client/cmd/login_test.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/wiretrustee/wiretrustee/client/internal"
|
||||||
|
"github.com/wiretrustee/wiretrustee/iface"
|
||||||
|
mgmt "github.com/wiretrustee/wiretrustee/management/server"
|
||||||
|
"github.com/wiretrustee/wiretrustee/util"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var mgmAddr string
|
||||||
|
|
||||||
|
func TestLogin_Start(t *testing.T) {
|
||||||
|
config := &mgmt.Config{}
|
||||||
|
_, err := util.ReadJson("../testdata/management.json", config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
testDir := t.TempDir()
|
||||||
|
config.Datadir = testDir
|
||||||
|
err = util.CopyFileContents("../testdata/store.json", filepath.Join(testDir, "store.json"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, listener := startManagement(config, t)
|
||||||
|
mgmAddr = listener.Addr().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLogin(t *testing.T) {
|
||||||
|
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
confPath := tempDir + "/config.json"
|
||||||
|
mgmtURL := fmt.Sprintf("http://%s", mgmAddr)
|
||||||
|
rootCmd.SetArgs([]string{
|
||||||
|
"login",
|
||||||
|
"--config",
|
||||||
|
confPath,
|
||||||
|
"--setup-key",
|
||||||
|
"a2c8e62b-38f5-4553-b31e-dd66c696cebb",
|
||||||
|
"--management-url",
|
||||||
|
mgmtURL,
|
||||||
|
})
|
||||||
|
err := rootCmd.Execute()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate generated config
|
||||||
|
actualConf := &internal.Config{}
|
||||||
|
_, err = util.ReadJson(confPath, actualConf)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected proper config file written, got broken %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if actualConf.ManagementURL.String() != mgmtURL {
|
||||||
|
t.Errorf("expected management URL %s got %s", mgmtURL, actualConf.ManagementURL.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if actualConf.WgIface != iface.WgInterfaceDefault {
|
||||||
|
t.Errorf("expected WgIface %s got %s", iface.WgInterfaceDefault, actualConf.WgIface)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(actualConf.PrivateKey) == 0 {
|
||||||
|
t.Errorf("expected non empty Private key, got empty")
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/wiretrustee/wiretrustee/client/internal"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -20,6 +21,7 @@ var (
|
|||||||
configPath string
|
configPath string
|
||||||
defaultConfigPath string
|
defaultConfigPath string
|
||||||
logLevel string
|
logLevel string
|
||||||
|
managementURL string
|
||||||
|
|
||||||
rootCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
Use: "wiretrustee",
|
Use: "wiretrustee",
|
||||||
@ -43,10 +45,13 @@ func init() {
|
|||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
defaultConfigPath = os.Getenv("PROGRAMDATA") + "\\Wiretrustee\\" + "config.json"
|
defaultConfigPath = os.Getenv("PROGRAMDATA") + "\\Wiretrustee\\" + "config.json"
|
||||||
}
|
}
|
||||||
rootCmd.PersistentFlags().StringVar(&configPath, "config", defaultConfigPath, "Wiretrustee config file location to write new config to")
|
|
||||||
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "")
|
rootCmd.PersistentFlags().StringVar(&managementURL, "management-url", "", fmt.Sprintf("Management Service URL [http|https]://[host]:[port] (default \"%s\")", internal.ManagementURLDefault().String()))
|
||||||
|
rootCmd.PersistentFlags().StringVar(&configPath, "config", defaultConfigPath, "Wiretrustee config file location")
|
||||||
|
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "sets Wiretrustee log level")
|
||||||
rootCmd.AddCommand(serviceCmd)
|
rootCmd.AddCommand(serviceCmd)
|
||||||
rootCmd.AddCommand(upCmd)
|
rootCmd.AddCommand(upCmd)
|
||||||
|
rootCmd.AddCommand(loginCmd)
|
||||||
serviceCmd.AddCommand(runCmd, startCmd, stopCmd, restartCmd) // service control commands are subcommands of service
|
serviceCmd.AddCommand(runCmd, startCmd, stopCmd, restartCmd) // service control commands are subcommands of service
|
||||||
serviceCmd.AddCommand(installCmd, uninstallCmd) // service installer commands are subcommands of service
|
serviceCmd.AddCommand(installCmd, uninstallCmd) // service installer commands are subcommands of service
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,6 @@ type program struct {
|
|||||||
args []string
|
args []string
|
||||||
}
|
}
|
||||||
|
|
||||||
var logger service.Logger
|
|
||||||
|
|
||||||
func newSVCConfig() *service.Config {
|
func newSVCConfig() *service.Config {
|
||||||
return &service.Config{
|
return &service.Config{
|
||||||
Name: "wiretrustee",
|
Name: "wiretrustee",
|
||||||
@ -27,11 +25,6 @@ func newSVC(prg *program, conf *service.Config) (service.Service, error) {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
logger, err = s.Logger(nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,8 +32,6 @@ var (
|
|||||||
serviceCmd = &cobra.Command{
|
serviceCmd = &cobra.Command{
|
||||||
Use: "service",
|
Use: "service",
|
||||||
Short: "manages wiretrustee service",
|
Short: "manages wiretrustee service",
|
||||||
//Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
//},
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -9,7 +9,13 @@ import (
|
|||||||
func (p *program) Start(s service.Service) error {
|
func (p *program) Start(s service.Service) error {
|
||||||
// Start should not block. Do the actual work async.
|
// Start should not block. Do the actual work async.
|
||||||
log.Info("starting service") //nolint
|
log.Info("starting service") //nolint
|
||||||
go upCmd.Run(p.cmd, p.args)
|
go func() {
|
||||||
|
err := upCmd.RunE(p.cmd, p.args)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/kardianos/service"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_ServiceInstallCMD(t *testing.T) {
|
|
||||||
b := bytes.NewBufferString("")
|
|
||||||
rootCmd.SetOut(b)
|
|
||||||
rootCmd.SetErr(b)
|
|
||||||
rootCmd.SetArgs([]string{
|
|
||||||
"service",
|
|
||||||
"install",
|
|
||||||
"--config",
|
|
||||||
"/tmp/config.json",
|
|
||||||
})
|
|
||||||
err := rootCmd.Execute()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
out, err := ioutil.ReadAll(b)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
expectedMSG := "Wiretrustee service has been installed"
|
|
||||||
if string(out) != expectedMSG {
|
|
||||||
t.Fatalf("expected \"%s\" got \"%s\"", expectedMSG, string(out))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_ServiceStartCMD(t *testing.T) {
|
|
||||||
b := bytes.NewBufferString("")
|
|
||||||
rootCmd.SetOut(b)
|
|
||||||
rootCmd.SetErr(b)
|
|
||||||
rootCmd.SetArgs([]string{"service", "start"})
|
|
||||||
err := rootCmd.Execute()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
out, err := ioutil.ReadAll(b)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
expectedMSG := "Wiretrustee service has been started"
|
|
||||||
if string(out) != expectedMSG {
|
|
||||||
t.Fatalf("expected \"%s\" got \"%s\"", expectedMSG, string(out))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_ServiceRunCMD(t *testing.T) {
|
|
||||||
configFilePath := "/tmp/config.json"
|
|
||||||
if _, err := os.Stat(configFilePath); err == nil {
|
|
||||||
e := os.Remove(configFilePath)
|
|
||||||
if e != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rootCmd.SetArgs([]string{
|
|
||||||
"--config",
|
|
||||||
configFilePath,
|
|
||||||
})
|
|
||||||
err := rootCmd.Execute()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rootCmd.ResetFlags()
|
|
||||||
rootCmd.SetArgs([]string{"service", "start"})
|
|
||||||
err = rootCmd.Execute()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
s, err := newSVC(&program{}, newSVCConfig())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
status, err := s.Status()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if status != service.StatusRunning {
|
|
||||||
t.Fatalf("expected running status of \"%d\" got \"%d\"", service.StatusRunning, status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*func Test_ServiceStopCMD(t *testing.T) {
|
|
||||||
b := bytes.NewBufferString("")
|
|
||||||
rootCmd.SetOut(b)
|
|
||||||
rootCmd.SetErr(b)
|
|
||||||
rootCmd.SetArgs([]string{"service", "stop"})
|
|
||||||
err := rootCmd.Execute()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
out, err := ioutil.ReadAll(b)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedMSG := "Wiretrustee service has been stopped"
|
|
||||||
if string(out) != expectedMSG {
|
|
||||||
t.Fatalf("expected \"%s\" got \"%s\"", expectedMSG, string(out))
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
func Test_ServiceUninstallCMD(t *testing.T) {
|
|
||||||
b := bytes.NewBufferString("")
|
|
||||||
rootCmd.SetOut(b)
|
|
||||||
rootCmd.SetErr(b)
|
|
||||||
rootCmd.SetArgs([]string{"service", "uninstall"})
|
|
||||||
err := rootCmd.Execute()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
out, err := ioutil.ReadAll(b)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
expectedMSG := "Wiretrustee has been uninstalled"
|
|
||||||
if string(out) != expectedMSG {
|
|
||||||
t.Fatalf("expected \"%s\" got \"%s\"", expectedMSG, string(out))
|
|
||||||
}
|
|
||||||
}
|
|
54
client/cmd/testutil.go
Normal file
54
client/cmd/testutil.go
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
mgmtProto "github.com/wiretrustee/wiretrustee/management/proto"
|
||||||
|
mgmt "github.com/wiretrustee/wiretrustee/management/server"
|
||||||
|
sigProto "github.com/wiretrustee/wiretrustee/signal/proto"
|
||||||
|
sig "github.com/wiretrustee/wiretrustee/signal/server"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func startSignal(t *testing.T) (*grpc.Server, net.Listener) {
|
||||||
|
lis, err := net.Listen("tcp", ":0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
s := grpc.NewServer()
|
||||||
|
sigProto.RegisterSignalExchangeServer(s, sig.NewServer())
|
||||||
|
go func() {
|
||||||
|
if err := s.Serve(lis); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return s, lis
|
||||||
|
}
|
||||||
|
|
||||||
|
func startManagement(config *mgmt.Config, t *testing.T) (*grpc.Server, net.Listener) {
|
||||||
|
lis, err := net.Listen("tcp", ":0")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
s := grpc.NewServer()
|
||||||
|
store, err := mgmt.NewStore(config.Datadir)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
accountManager := mgmt.NewManager(store)
|
||||||
|
mgmtServer, err := mgmt.NewServer(config, accountManager)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
mgmtProto.RegisterManagementServiceServer(s, mgmtServer)
|
||||||
|
go func() {
|
||||||
|
if err := s.Serve(lis); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return s, lis
|
||||||
|
}
|
117
client/cmd/up.go
117
client/cmd/up.go
@ -1,9 +1,7 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"github.com/pion/ice/v2"
|
"github.com/pion/ice/v2"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -15,64 +13,58 @@ import (
|
|||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
managementAddr string
|
|
||||||
|
|
||||||
upCmd = &cobra.Command{
|
upCmd = &cobra.Command{
|
||||||
Use: "up",
|
Use: "up",
|
||||||
Short: "start wiretrustee",
|
Short: "start wiretrustee",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
InitLog(logLevel)
|
InitLog(logLevel)
|
||||||
|
|
||||||
config, err := internal.GetConfig(managementAddr, configPath)
|
config, err := internal.ReadConfig(managementURL, configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed getting config %s %v", configPath, err)
|
log.Errorf("failed reading config %s %v", configPath, err)
|
||||||
os.Exit(ExitSetupFailed)
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//validate our peer's Wireguard PRIVATE key
|
//validate our peer's Wireguard PRIVATE key
|
||||||
myPrivateKey, err := wgtypes.ParseKey(config.PrivateKey)
|
myPrivateKey, err := wgtypes.ParseKey(config.PrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed parsing Wireguard key %s: [%s]", config.PrivateKey, err.Error())
|
log.Errorf("failed parsing Wireguard key %s: [%s]", config.PrivateKey, err.Error())
|
||||||
os.Exit(ExitSetupFailed)
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
managementURL, err := url.Parse(config.ManagementURL)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("failed parsing managemtn URL%s: [%s]", config.ManagementURL, err.Error())
|
|
||||||
os.Exit(ExitSetupFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
mgmTlsEnabled := false
|
mgmTlsEnabled := false
|
||||||
if managementURL.Scheme == "https" {
|
if config.ManagementURL.Scheme == "https" {
|
||||||
mgmTlsEnabled = true
|
mgmTlsEnabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// connect (just a connection, no stream yet) and login to Management Service to get an initial global Wiretrustee config
|
// connect (just a connection, no stream yet) and login to Management Service to get an initial global Wiretrustee config
|
||||||
|
mgmClient, loginResp, err := connectToManagement(ctx, config.ManagementURL.Host, myPrivateKey, mgmTlsEnabled)
|
||||||
mgmClient, loginResp, err := connectToManagement(ctx, managementURL.Host, myPrivateKey, mgmTlsEnabled)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Warn(err)
|
||||||
os.Exit(ExitSetupFailed)
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// with the global Wiretrustee config in hand connect (just a connection, no stream yet) Signal
|
// with the global Wiretrustee config in hand connect (just a connection, no stream yet) Signal
|
||||||
signalClient, err := connectToSignal(ctx, loginResp.GetWiretrusteeConfig(), myPrivateKey)
|
signalClient, err := connectToSignal(ctx, loginResp.GetWiretrusteeConfig(), myPrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
os.Exit(ExitSetupFailed)
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
engineConfig, err := createEngineConfig(myPrivateKey, config, loginResp.GetWiretrusteeConfig(), loginResp.GetPeerConfig())
|
engineConfig, err := createEngineConfig(myPrivateKey, config, loginResp.GetWiretrusteeConfig(), loginResp.GetPeerConfig())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
os.Exit(ExitSetupFailed)
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// create start the Wiretrustee Engine that will connect to the Signal and Management streams and manage connections to remote peers.
|
// create start the Wiretrustee Engine that will connect to the Signal and Management streams and manage connections to remote peers.
|
||||||
@ -80,7 +72,8 @@ var (
|
|||||||
err = engine.Start()
|
err = engine.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("error while starting Wiretrustee Connection Engine: %s", err)
|
log.Errorf("error while starting Wiretrustee Connection Engine: %s", err)
|
||||||
os.Exit(ExitSetupFailed)
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupCloseHandler()
|
SetupCloseHandler()
|
||||||
@ -89,23 +82,30 @@ var (
|
|||||||
err = mgmClient.Close()
|
err = mgmClient.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed closing Management Service client %v", err)
|
log.Errorf("failed closing Management Service client %v", err)
|
||||||
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
err = signalClient.Close()
|
err = signalClient.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed closing Signal Service client %v", err)
|
log.Errorf("failed closing Signal Service client %v", err)
|
||||||
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("removing Wiretrustee interface %s", config.WgIface)
|
log.Debugf("removing Wiretrustee interface %s", config.WgIface)
|
||||||
err = iface.Close()
|
err = iface.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed closing Wiretrustee interface %s %v", config.WgIface, err)
|
log.Errorf("failed closing Wiretrustee interface %s %v", config.WgIface, err)
|
||||||
|
//os.Exit(ExitSetupFailed)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
upCmd.PersistentFlags().StringVar(&managementAddr, "management-addr", "", "Management Service address (e.g. app.wiretrustee.com")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// createEngineConfig converts configuration received from Management Service to EngineConfig
|
// createEngineConfig converts configuration received from Management Service to EngineConfig
|
||||||
@ -161,6 +161,7 @@ func connectToSignal(ctx context.Context, wtConfig *mgmProto.WiretrusteeConfig,
|
|||||||
} else {
|
} else {
|
||||||
sigTLSEnabled = false
|
sigTLSEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
signalClient, err := signal.NewClient(ctx, wtConfig.Signal.Uri, ourPrivateKey, sigTLSEnabled)
|
signalClient, err := signal.NewClient(ctx, wtConfig.Signal.Uri, ourPrivateKey, sigTLSEnabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("error while connecting to the Signal Exchange Service %s: %s", wtConfig.Signal.Uri, err)
|
log.Errorf("error while connecting to the Signal Exchange Service %s: %s", wtConfig.Signal.Uri, err)
|
||||||
@ -170,75 +171,31 @@ func connectToSignal(ctx context.Context, wtConfig *mgmProto.WiretrusteeConfig,
|
|||||||
return signalClient, nil
|
return signalClient, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// connectToManagement creates Management Services client, establishes a connection and gets a global Wiretrustee config (signal, turn, stun hosts, etc)
|
// connectToManagement creates Management Services client, establishes a connection, logs-in and gets a global Wiretrustee config (signal, turn, stun hosts, etc)
|
||||||
func connectToManagement(ctx context.Context, managementAddr string, ourPrivateKey wgtypes.Key, tlsEnabled bool) (*mgm.Client, *mgmProto.LoginResponse, error) {
|
func connectToManagement(ctx context.Context, managementAddr string, ourPrivateKey wgtypes.Key, tlsEnabled bool) (*mgm.Client, *mgmProto.LoginResponse, error) {
|
||||||
log.Debugf("connecting to management server %s", managementAddr)
|
log.Debugf("connecting to management server %s", managementAddr)
|
||||||
mgmClient, err := mgm.NewClient(ctx, managementAddr, ourPrivateKey, tlsEnabled)
|
client, err := mgm.NewClient(ctx, managementAddr, ourPrivateKey, tlsEnabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, status.Errorf(codes.FailedPrecondition, "failed connecting to Management Service : %s", err)
|
return nil, nil, status.Errorf(codes.FailedPrecondition, "failed connecting to Management Service : %s", err)
|
||||||
}
|
}
|
||||||
log.Debugf("connected to management server %s", managementAddr)
|
log.Debugf("connected to management server %s", managementAddr)
|
||||||
|
|
||||||
serverKey, err := mgmClient.GetServerPublicKey()
|
serverPublicKey, err := client.GetServerPublicKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, status.Errorf(codes.FailedPrecondition, "failed while getting Management Service public key: %s", err)
|
return nil, nil, status.Errorf(codes.FailedPrecondition, "failed while getting Management Service public key: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
wtConfig, err := loginPeer(*serverKey, mgmClient)
|
loginResp, err := client.Login(*serverPublicKey)
|
||||||
if err != nil {
|
|
||||||
return nil, nil, status.Errorf(codes.FailedPrecondition, "failed logging-in peer on Management Service : %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("peer logged in to Management Service %s", wtConfig)
|
|
||||||
|
|
||||||
return mgmClient, wtConfig, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func registerPeer(serverPublicKey wgtypes.Key, client *mgm.Client) (*mgmProto.LoginResponse, error) {
|
|
||||||
setupKey, err := promptPeerSetupKey()
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("failed getting setup key: %s", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("sending peer registration request")
|
|
||||||
loginResp, err := client.Register(serverPublicKey, *setupKey)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("failed registering peer %v", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return loginResp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loginPeer(serverPublicKey wgtypes.Key, client *mgm.Client) (*mgmProto.LoginResponse, error) {
|
|
||||||
|
|
||||||
loginResp, err := client.Login(serverPublicKey)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if s, ok := status.FromError(err); ok && s.Code() == codes.PermissionDenied {
|
if s, ok := status.FromError(err); ok && s.Code() == codes.PermissionDenied {
|
||||||
log.Debugf("peer registration required")
|
log.Error("peer registration required. Please run wiretrustee login command first")
|
||||||
return registerPeer(serverPublicKey, client)
|
return nil, nil, err
|
||||||
} else {
|
} else {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return loginResp, nil
|
log.Infof("peer logged in to Management Service %s", managementAddr)
|
||||||
}
|
|
||||||
|
return client, loginResp, nil
|
||||||
// promptPeerSetupKey prompts user to input a Setup Key
|
|
||||||
func promptPeerSetupKey() (*string, error) {
|
|
||||||
fmt.Print("Enter setup key: ")
|
|
||||||
|
|
||||||
s := bufio.NewScanner(os.Stdin)
|
|
||||||
for s.Scan() {
|
|
||||||
input := s.Text()
|
|
||||||
if input != "" {
|
|
||||||
return &input, nil
|
|
||||||
}
|
|
||||||
fmt.Println("Specified key is empty, try again:")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, s.Err()
|
|
||||||
}
|
}
|
||||||
|
110
client/cmd/up_test.go
Normal file
110
client/cmd/up_test.go
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/wiretrustee/wiretrustee/iface"
|
||||||
|
mgmt "github.com/wiretrustee/wiretrustee/management/server"
|
||||||
|
"github.com/wiretrustee/wiretrustee/util"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var signalAddr string
|
||||||
|
|
||||||
|
func TestUp_Start(t *testing.T) {
|
||||||
|
config := &mgmt.Config{}
|
||||||
|
_, err := util.ReadJson("../testdata/management.json", config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
testDir := t.TempDir()
|
||||||
|
config.Datadir = testDir
|
||||||
|
err = util.CopyFileContents("../testdata/store.json", filepath.Join(testDir, "store.json"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, signalLis := startSignal(t)
|
||||||
|
signalAddr = signalLis.Addr().String()
|
||||||
|
config.Signal.URI = signalAddr
|
||||||
|
|
||||||
|
_, mgmLis := startManagement(config, t)
|
||||||
|
mgmAddr = mgmLis.Addr().String()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUp_ShouldFail_On_NoConfig(t *testing.T) {
|
||||||
|
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
confPath := tempDir + "/config.json"
|
||||||
|
mgmtURL := fmt.Sprintf("http://%s", mgmAddr)
|
||||||
|
rootCmd.SetArgs([]string{
|
||||||
|
"up",
|
||||||
|
"--config",
|
||||||
|
confPath,
|
||||||
|
"--management-url",
|
||||||
|
mgmtURL,
|
||||||
|
})
|
||||||
|
err := rootCmd.Execute()
|
||||||
|
if err == nil || !errors.Is(err, os.ErrNotExist) {
|
||||||
|
t.Errorf("expecting login command to fail on absence of config")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUp(t *testing.T) {
|
||||||
|
|
||||||
|
defer iface.Close()
|
||||||
|
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
confPath := tempDir + "/config.json"
|
||||||
|
mgmtURL, err := url.Parse("http://" + mgmAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
rootCmd.SetArgs([]string{
|
||||||
|
"login",
|
||||||
|
"--config",
|
||||||
|
confPath,
|
||||||
|
"--setup-key",
|
||||||
|
"a2c8e62b-38f5-4553-b31e-dd66c696cebb",
|
||||||
|
"--management-url",
|
||||||
|
mgmtURL.String(),
|
||||||
|
})
|
||||||
|
err = rootCmd.Execute()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rootCmd.SetArgs([]string{
|
||||||
|
"up",
|
||||||
|
"--config",
|
||||||
|
confPath,
|
||||||
|
})
|
||||||
|
go func() {
|
||||||
|
err = rootCmd.Execute()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error while running up command, got %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
exists := false
|
||||||
|
for start := time.Now(); time.Since(start) < 7*time.Second; {
|
||||||
|
e, err := iface.Exists(iface.WgInterfaceDefault)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if *e {
|
||||||
|
exists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
t.Errorf("expected wireguard interface %s to be created", iface.WgInterfaceDefault)
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +1,34 @@
|
|||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/wiretrustee/wiretrustee/iface"
|
"github.com/wiretrustee/wiretrustee/iface"
|
||||||
"github.com/wiretrustee/wiretrustee/util"
|
"github.com/wiretrustee/wiretrustee/util"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ManagementAddrDefault = "https://app.wiretrustee.com"
|
var managementURLDefault *url.URL
|
||||||
|
|
||||||
|
func ManagementURLDefault() *url.URL {
|
||||||
|
return managementURLDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
managementURL, err := parseManagementURL("https://api.wiretrustee.com:33073")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
managementURLDefault = managementURL
|
||||||
|
}
|
||||||
|
|
||||||
// Config Configuration type
|
// Config Configuration type
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// Wireguard private key of local peer
|
// Wireguard private key of local peer
|
||||||
PrivateKey string
|
PrivateKey string
|
||||||
ManagementURL string
|
ManagementURL *url.URL
|
||||||
WgIface string
|
WgIface string
|
||||||
IFaceBlackList []string
|
IFaceBlackList []string
|
||||||
}
|
}
|
||||||
@ -24,11 +38,17 @@ func createNewConfig(managementURL string, configPath string) (*Config, error) {
|
|||||||
wgKey := generateKey()
|
wgKey := generateKey()
|
||||||
config := &Config{PrivateKey: wgKey, WgIface: iface.WgInterfaceDefault, IFaceBlackList: []string{}}
|
config := &Config{PrivateKey: wgKey, WgIface: iface.WgInterfaceDefault, IFaceBlackList: []string{}}
|
||||||
if managementURL != "" {
|
if managementURL != "" {
|
||||||
config.ManagementURL = managementURL
|
URL, err := parseManagementURL(managementURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.ManagementURL = URL
|
||||||
} else {
|
} else {
|
||||||
config.ManagementURL = ManagementAddrDefault
|
config.ManagementURL = managementURLDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config.IFaceBlackList = []string{iface.WgInterfaceDefault, "tun0"}
|
||||||
|
|
||||||
err := util.WriteJson(configPath, config)
|
err := util.WriteJson(configPath, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -37,29 +57,50 @@ func createNewConfig(managementURL string, configPath string) (*Config, error) {
|
|||||||
return config, nil
|
return config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConfig reads existing config or generates a new one
|
func parseManagementURL(managementURL string) (*url.URL, error) {
|
||||||
func GetConfig(managementURL string, configPath string) (*Config, error) {
|
|
||||||
|
|
||||||
var config *Config
|
parsedMgmtURL, err := url.ParseRequestURI(managementURL)
|
||||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
if err != nil {
|
||||||
log.Warnf("first run - generating new config %s", configPath)
|
log.Errorf("failed parsing management URL %s: [%s]", managementURL, err.Error())
|
||||||
config, err = createNewConfig(managementURL, configPath)
|
return nil, err
|
||||||
if err != nil {
|
}
|
||||||
return nil, err
|
|
||||||
}
|
if !(parsedMgmtURL.Scheme == "https" || parsedMgmtURL.Scheme == "http") {
|
||||||
} else {
|
return nil, fmt.Errorf("invalid Management Service URL provided %s. Supported format [http|https]://[host]:[port]", managementURL)
|
||||||
config = &Config{}
|
}
|
||||||
_, err := util.ReadJson(configPath, config)
|
|
||||||
if err != nil {
|
return parsedMgmtURL, err
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadConfig reads existing config. In case provided managementURL is not empty overrides the read property
|
||||||
|
func ReadConfig(managementURL string, configPath string) (*Config, error) {
|
||||||
|
config := &Config{}
|
||||||
|
_, err := util.ReadJson(configPath, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if managementURL != "" {
|
if managementURL != "" {
|
||||||
config.ManagementURL = managementURL
|
URL, err := parseManagementURL(managementURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.ManagementURL = URL
|
||||||
}
|
}
|
||||||
|
|
||||||
return config, nil
|
return config, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConfig reads existing config or generates a new one
|
||||||
|
func GetConfig(managementURL string, configPath string) (*Config, error) {
|
||||||
|
|
||||||
|
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||||
|
log.Infof("generating new config %s", configPath)
|
||||||
|
return createNewConfig(managementURL, configPath)
|
||||||
|
} else {
|
||||||
|
return ReadConfig(managementURL, configPath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateKey generates a new Wireguard private key
|
// generateKey generates a new Wireguard private key
|
||||||
|
33
client/testdata/management.json
vendored
Normal file
33
client/testdata/management.json
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"Stuns": [
|
||||||
|
{
|
||||||
|
"Proto": "udp",
|
||||||
|
"URI": "stun:stun.wiretrustee.com:3468",
|
||||||
|
"Username": "",
|
||||||
|
"Password": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Turns": [
|
||||||
|
{
|
||||||
|
"Proto": "udp",
|
||||||
|
"URI": "turn:stun.wiretrustee.com:3468",
|
||||||
|
"Username": "some_user",
|
||||||
|
"Password": "c29tZV9wYXNzd29yZA=="
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Signal": {
|
||||||
|
"Proto": "http",
|
||||||
|
"URI": "signal.wiretrustee.com:10000",
|
||||||
|
"Username": "",
|
||||||
|
"Password": null
|
||||||
|
},
|
||||||
|
"DataDir": "",
|
||||||
|
"HttpConfig": {
|
||||||
|
"LetsEncryptDomain": "",
|
||||||
|
"Address": "0.0.0.0:3000",
|
||||||
|
"AuthDomain": "<PASTE YOUR AUTH0 DOMAIN HERE>",
|
||||||
|
"AuthClientId": "<PASTE YOUR AUTH0 CLIENT ID HERE>",
|
||||||
|
"AuthClientSecret": "<PASTE YOUR AUTH0 SECRET>",
|
||||||
|
"AuthCallback": "http://localhost:3000/callback"
|
||||||
|
}
|
||||||
|
}
|
21
client/testdata/store.json
vendored
Normal file
21
client/testdata/store.json
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"Accounts": {
|
||||||
|
"bf1c8084-ba50-4ce7-9439-34653001fc3b": {
|
||||||
|
"Id": "bf1c8084-ba50-4ce7-9439-34653001fc3b",
|
||||||
|
"SetupKeys": {
|
||||||
|
"a2c8e62b-38f5-4553-b31e-dd66c696cebb": {
|
||||||
|
"Key": "a2c8e62b-38f5-4553-b31e-dd66c696cebb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Network": {
|
||||||
|
"Id": "af1c8024-ha40-4ce2-9418-34653101fc3c",
|
||||||
|
"Net": {
|
||||||
|
"IP": "100.64.0.0",
|
||||||
|
"Mask": "/8AAAA=="
|
||||||
|
},
|
||||||
|
"Dns": null
|
||||||
|
},
|
||||||
|
"Peers": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -31,8 +31,10 @@ func NewClient(ctx context.Context, addr string, ourPrivateKey wgtypes.Key, tlsE
|
|||||||
transportOption = grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))
|
transportOption = grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mgmCtx, cancel := context.WithTimeout(ctx, 3*time.Second)
|
||||||
|
defer cancel()
|
||||||
conn, err := grpc.DialContext(
|
conn, err := grpc.DialContext(
|
||||||
ctx,
|
mgmCtx,
|
||||||
addr,
|
addr,
|
||||||
transportOption,
|
transportOption,
|
||||||
grpc.WithBlock(),
|
grpc.WithBlock(),
|
||||||
|
@ -48,8 +48,10 @@ func NewClient(ctx context.Context, addr string, key wgtypes.Key, tlsEnabled boo
|
|||||||
transportOption = grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))
|
transportOption = grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sigCtx, cancel := context.WithTimeout(ctx, 3*time.Second)
|
||||||
|
defer cancel()
|
||||||
conn, err := grpc.DialContext(
|
conn, err := grpc.DialContext(
|
||||||
ctx,
|
sigCtx,
|
||||||
addr,
|
addr,
|
||||||
transportOption,
|
transportOption,
|
||||||
grpc.WithBlock(),
|
grpc.WithBlock(),
|
||||||
|
Loading…
Reference in New Issue
Block a user