mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-22 13:29:08 +02:00
Add Settings window to Agent UI
Agent systray UI has been extended with a setting window that allows configuring management URL, admin URL and supports pre-shared key. While for the Netbird managed version the Settings are not necessary, it helps to properly configure the self-hosted version.
This commit is contained in:
+56
-27
@@ -2,12 +2,13 @@ package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"github.com/netbirdio/netbird/iface"
|
||||
"github.com/netbirdio/netbird/util"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
"net/url"
|
||||
"os"
|
||||
)
|
||||
|
||||
var managementURLDefault *url.URL
|
||||
@@ -17,7 +18,7 @@ func ManagementURLDefault() *url.URL {
|
||||
}
|
||||
|
||||
func init() {
|
||||
managementURL, err := parseManagementURL("https://api.wiretrustee.com:33073")
|
||||
managementURL, err := parseURL("Management URL", "https://api.wiretrustee.com:33073")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -30,16 +31,17 @@ type Config struct {
|
||||
PrivateKey string
|
||||
PreSharedKey string
|
||||
ManagementURL *url.URL
|
||||
AdminURL *url.URL
|
||||
WgIface string
|
||||
IFaceBlackList []string
|
||||
}
|
||||
|
||||
//createNewConfig creates a new config generating a new Wireguard key and saving to file
|
||||
func createNewConfig(managementURL string, configPath string, preSharedKey string) (*Config, error) {
|
||||
// createNewConfig creates a new config generating a new Wireguard key and saving to file
|
||||
func createNewConfig(managementURL, adminURL, configPath, preSharedKey string) (*Config, error) {
|
||||
wgKey := generateKey()
|
||||
config := &Config{PrivateKey: wgKey, WgIface: iface.WgInterfaceDefault, IFaceBlackList: []string{}}
|
||||
if managementURL != "" {
|
||||
URL, err := parseManagementURL(managementURL)
|
||||
URL, err := parseURL("Management URL", managementURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -62,55 +64,82 @@ func createNewConfig(managementURL string, configPath string, preSharedKey strin
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func parseManagementURL(managementURL string) (*url.URL, error) {
|
||||
|
||||
func parseURL(serviceName, managementURL string) (*url.URL, error) {
|
||||
parsedMgmtURL, err := url.ParseRequestURI(managementURL)
|
||||
if err != nil {
|
||||
log.Errorf("failed parsing management URL %s: [%s]", managementURL, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !(parsedMgmtURL.Scheme == "https" || parsedMgmtURL.Scheme == "http") {
|
||||
return nil, fmt.Errorf("invalid Management Service URL provided %s. Supported format [http|https]://[host]:[port]", managementURL)
|
||||
if parsedMgmtURL.Scheme != "https" && parsedMgmtURL.Scheme != "http" {
|
||||
return nil, fmt.Errorf(
|
||||
"invalid %s URL provided %s. Supported format [http|https]://[host]:[port]",
|
||||
serviceName, managementURL)
|
||||
}
|
||||
|
||||
return parsedMgmtURL, err
|
||||
|
||||
}
|
||||
|
||||
// ReadConfig reads existing config. In case provided managementURL is not empty overrides the read property
|
||||
func ReadConfig(managementURL string, configPath string) (*Config, error) {
|
||||
func ReadConfig(managementURL, adminURL, configPath string, preSharedKey *string) (*Config, error) {
|
||||
config := &Config{}
|
||||
_, err := util.ReadJson(configPath, config)
|
||||
if err != nil {
|
||||
if _, err := util.ReadJson(configPath, config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
refresh := false
|
||||
|
||||
if managementURL != "" && config.ManagementURL.String() != managementURL {
|
||||
URL, err := parseManagementURL(managementURL)
|
||||
log.Infof("new Management URL provided, updated to %s (old value %s)",
|
||||
managementURL, config.ManagementURL)
|
||||
newURL, err := parseURL("Management URL", managementURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.ManagementURL = URL
|
||||
// since we have new management URL, we need to update config file
|
||||
err = util.WriteJson(configPath, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Infof("new Management URL provided, updated to %s (old value %s)", managementURL, config.ManagementURL)
|
||||
config.ManagementURL = newURL
|
||||
refresh = true
|
||||
}
|
||||
|
||||
return config, err
|
||||
if adminURL != "" && (config.AdminURL == nil || config.AdminURL.String() != adminURL) {
|
||||
log.Infof("new Admin Panel URL provided, updated to %s (old value %s)",
|
||||
adminURL, config.AdminURL)
|
||||
newURL, err := parseURL("Admin Panel URL", adminURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.AdminURL = newURL
|
||||
refresh = true
|
||||
}
|
||||
|
||||
if preSharedKey != nil && config.PreSharedKey != *preSharedKey {
|
||||
log.Infof("new pre-shared key provided, updated to %s (old value %s)",
|
||||
*preSharedKey, config.PreSharedKey)
|
||||
config.PreSharedKey = *preSharedKey
|
||||
refresh = true
|
||||
}
|
||||
|
||||
if refresh {
|
||||
// since we have new management URL, we need to update config file
|
||||
if err := util.WriteJson(configPath, config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// GetConfig reads existing config or generates a new one
|
||||
func GetConfig(managementURL string, configPath string, preSharedKey string) (*Config, error) {
|
||||
|
||||
func GetConfig(managementURL, adminURL, configPath, preSharedKey string) (*Config, error) {
|
||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||
log.Infof("generating new config %s", configPath)
|
||||
return createNewConfig(managementURL, configPath, preSharedKey)
|
||||
return createNewConfig(managementURL, adminURL, configPath, preSharedKey)
|
||||
} else {
|
||||
return ReadConfig(managementURL, configPath)
|
||||
// don't overwrite pre-shared key if we receive asterisks from UI
|
||||
pk := &preSharedKey
|
||||
if preSharedKey == "**********" {
|
||||
pk = nil
|
||||
}
|
||||
return ReadConfig(managementURL, adminURL, configPath, pk)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,24 +2,25 @@ package internal
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/netbirdio/netbird/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/netbirdio/netbird/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestReadConfig(t *testing.T) {
|
||||
|
||||
}
|
||||
func TestGetConfig(t *testing.T) {
|
||||
|
||||
func TestGetConfig(t *testing.T) {
|
||||
managementURL := "https://test.management.url:33071"
|
||||
adminURL := "https://app.admin.url"
|
||||
path := filepath.Join(t.TempDir(), "config.json")
|
||||
preSharedKey := "preSharedKey"
|
||||
|
||||
// case 1: new config has to be generated
|
||||
config, err := GetConfig(managementURL, path, preSharedKey)
|
||||
config, err := GetConfig(managementURL, adminURL, path, preSharedKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -32,7 +33,7 @@ func TestGetConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
// case 2: existing config -> fetch it
|
||||
config, err = GetConfig(managementURL, path, preSharedKey)
|
||||
config, err = GetConfig(managementURL, adminURL, path, preSharedKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -42,7 +43,7 @@ func TestGetConfig(t *testing.T) {
|
||||
|
||||
// case 3: existing config, but new managementURL has been provided -> update config
|
||||
newManagementURL := "https://test.newManagement.url:33071"
|
||||
config, err = GetConfig(newManagementURL, path, preSharedKey)
|
||||
config, err = GetConfig(newManagementURL, adminURL, path, preSharedKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -56,5 +57,4 @@ func TestGetConfig(t *testing.T) {
|
||||
return
|
||||
}
|
||||
assert.Equal(t, readConf.(*Config).ManagementURL.String(), newManagementURL)
|
||||
|
||||
}
|
||||
|
||||
+19
-43
@@ -2,9 +2,7 @@ package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
"github.com/google/uuid"
|
||||
"github.com/netbirdio/netbird/client/system"
|
||||
mgm "github.com/netbirdio/netbird/management/client"
|
||||
@@ -16,16 +14,6 @@ import (
|
||||
)
|
||||
|
||||
func Login(ctx context.Context, config *Config, setupKey string) error {
|
||||
backOff := &backoff.ExponentialBackOff{
|
||||
InitialInterval: time.Second,
|
||||
RandomizationFactor: backoff.DefaultRandomizationFactor,
|
||||
Multiplier: backoff.DefaultMultiplier,
|
||||
MaxInterval: 2 * time.Second,
|
||||
MaxElapsedTime: time.Second * 10,
|
||||
Stop: backoff.Stop,
|
||||
Clock: backoff.SystemClock,
|
||||
}
|
||||
|
||||
// validate our peer's Wireguard PRIVATE key
|
||||
myPrivateKey, err := wgtypes.ParseKey(config.PrivateKey)
|
||||
if err != nil {
|
||||
@@ -38,41 +26,29 @@ func Login(ctx context.Context, config *Config, setupKey string) error {
|
||||
mgmTlsEnabled = true
|
||||
}
|
||||
|
||||
loginOp := func() error {
|
||||
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)
|
||||
return err
|
||||
}
|
||||
log.Debugf("connected to management Service %s", config.ManagementURL.String())
|
||||
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)
|
||||
return err
|
||||
}
|
||||
log.Debugf("connected to management Service %s", config.ManagementURL.String())
|
||||
|
||||
serverKey, err := mgmClient.GetServerPublicKey()
|
||||
if err != nil {
|
||||
log.Errorf("failed while getting Management Service public key: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = loginPeer(*serverKey, mgmClient, setupKey)
|
||||
if err != nil {
|
||||
log.Errorf("failed logging-in peer on Management Service : %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = mgmClient.Close()
|
||||
if err != nil {
|
||||
log.Errorf("failed closing Management Service client: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
serverKey, err := mgmClient.GetServerPublicKey()
|
||||
if err != nil {
|
||||
log.Errorf("failed while getting Management Service public key: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = backoff.RetryNotify(loginOp, backOff, func(err error, duration time.Duration) {
|
||||
log.Warnf("retrying Login to the Management service in %v due to error %v", duration, err)
|
||||
})
|
||||
_, err = loginPeer(*serverKey, mgmClient, setupKey)
|
||||
if err != nil {
|
||||
log.Errorf("exiting login retry loop due to unrecoverable error: %v", err)
|
||||
log.Errorf("failed logging-in peer on Management Service : %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = mgmClient.Close()
|
||||
if err != nil {
|
||||
log.Errorf("failed closing Management Service client: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user