From ca62f6787af54b62b6080b719d58569a8296f747 Mon Sep 17 00:00:00 2001 From: Maycon Santos Date: Sun, 8 Jan 2023 12:57:28 +0100 Subject: [PATCH] Use configuration input struct (#645) As we will be passing more flags to configure local agents, we need a more flexible type --- client/cmd/login.go | 7 +++- client/cmd/ssh.go | 4 +- client/cmd/up.go | 7 +++- client/internal/config.go | 69 +++++++++++++++++++--------------- client/internal/config_test.go | 21 +++++++++-- client/internal/connect.go | 5 ++- client/server/server.go | 19 ++++++++-- 7 files changed, 91 insertions(+), 41 deletions(-) diff --git a/client/cmd/login.go b/client/cmd/login.go index 1b9e53f05..6a15b5a3e 100644 --- a/client/cmd/login.go +++ b/client/cmd/login.go @@ -38,7 +38,12 @@ var loginCmd = &cobra.Command{ return err } - config, err := internal.GetConfig(managementURL, adminURL, configPath, preSharedKey) + config, err := internal.GetConfig(internal.ConfigInput{ + ManagementURL: managementURL, + AdminURL: adminURL, + ConfigPath: configPath, + PreSharedKey: &preSharedKey, + }) if err != nil { return fmt.Errorf("get config file: %v", err) } diff --git a/client/cmd/ssh.go b/client/cmd/ssh.go index feb59e7b9..add41397e 100644 --- a/client/cmd/ssh.go +++ b/client/cmd/ssh.go @@ -56,7 +56,9 @@ var sshCmd = &cobra.Command{ ctx := internal.CtxInitState(cmd.Context()) - config, err := internal.ReadConfig("", "", configPath, nil) + config, err := internal.ReadConfig(internal.ConfigInput{ + ConfigPath: configPath, + }) if err != nil { return err } diff --git a/client/cmd/up.go b/client/cmd/up.go index 2501dcb7a..c12e1483d 100644 --- a/client/cmd/up.go +++ b/client/cmd/up.go @@ -35,7 +35,12 @@ var upCmd = &cobra.Command{ return err } - config, err := internal.GetConfig(managementURL, adminURL, configPath, preSharedKey) + config, err := internal.GetConfig(internal.ConfigInput{ + ManagementURL: managementURL, + AdminURL: adminURL, + ConfigPath: configPath, + PreSharedKey: &preSharedKey, + }) if err != nil { return fmt.Errorf("get config file: %v", err) } diff --git a/client/internal/config.go b/client/internal/config.go index 6420eb1de..2d73b9990 100644 --- a/client/internal/config.go +++ b/client/internal/config.go @@ -30,6 +30,14 @@ func init() { managementURLDefault = managementURL } +// ConfigInput carries configuration changes to the client +type ConfigInput struct { + ManagementURL string + AdminURL string + ConfigPath string + PreSharedKey *string +} + // Config Configuration type type Config struct { // Wireguard private key of local peer @@ -42,7 +50,7 @@ type Config struct { IFaceBlackList []string DisableIPv6Discovery bool // SSHKey is a private SSH key in a PEM format - SSHKey string + SSHKey string // ExternalIP mappings, if different than the host interface IP // @@ -63,7 +71,7 @@ type Config struct { } // createNewConfig creates a new config generating a new Wireguard key and saving to file -func createNewConfig(managementURL, adminURL, configPath, preSharedKey string) (*Config, error) { +func createNewConfig(input ConfigInput) (*Config, error) { wgKey := generateKey() pem, err := ssh.GeneratePrivateKey(ssh.ED25519) if err != nil { @@ -77,8 +85,8 @@ func createNewConfig(managementURL, adminURL, configPath, preSharedKey string) ( IFaceBlackList: []string{}, DisableIPv6Discovery: false, } - if managementURL != "" { - URL, err := ParseURL("Management URL", managementURL) + if input.ManagementURL != "" { + URL, err := ParseURL("Management URL", input.ManagementURL) if err != nil { return nil, err } @@ -87,22 +95,22 @@ func createNewConfig(managementURL, adminURL, configPath, preSharedKey string) ( config.ManagementURL = managementURLDefault } - if preSharedKey != "" { - config.PreSharedKey = preSharedKey + if input.PreSharedKey != nil { + config.PreSharedKey = *input.PreSharedKey } - if adminURL != "" { - newURL, err := ParseURL("Admin Panel URL", adminURL) + if input.AdminURL != "" { + newURL, err := ParseURL("Admin Panel URL", input.AdminURL) if err != nil { return nil, err } config.AdminURL = newURL } - config.IFaceBlackList = []string{iface.WgInterfaceDefault, "wt", "utun", "tun0", "zt", "ZeroTier", "utun", "wg", "ts", + config.IFaceBlackList = []string{iface.WgInterfaceDefault, "wt", "utun", "tun0", "zt", "ZeroTier", "wg", "ts", "Tailscale", "tailscale", "docker", "veth", "br-"} - err = util.WriteJson(configPath, config) + err = util.WriteJson(input.ConfigPath, config) if err != nil { return nil, err } @@ -128,22 +136,22 @@ func ParseURL(serviceName, managementURL string) (*url.URL, error) { } // ReadConfig reads existing config. In case provided managementURL is not empty overrides the read property -func ReadConfig(managementURL, adminURL, configPath string, preSharedKey *string) (*Config, error) { +func ReadConfig(input ConfigInput) (*Config, error) { config := &Config{} - if _, err := os.Stat(configPath); os.IsNotExist(err) { + if _, err := os.Stat(input.ConfigPath); os.IsNotExist(err) { return nil, status.Errorf(codes.NotFound, "config file doesn't exist") } - if _, err := util.ReadJson(configPath, config); err != nil { + if _, err := util.ReadJson(input.ConfigPath, config); err != nil { return nil, err } refresh := false - if managementURL != "" && config.ManagementURL.String() != managementURL { + if input.ManagementURL != "" && config.ManagementURL.String() != input.ManagementURL { log.Infof("new Management URL provided, updated to %s (old value %s)", - managementURL, config.ManagementURL) - newURL, err := ParseURL("Management URL", managementURL) + input.ManagementURL, config.ManagementURL) + newURL, err := ParseURL("Management URL", input.ManagementURL) if err != nil { return nil, err } @@ -151,10 +159,10 @@ func ReadConfig(managementURL, adminURL, configPath string, preSharedKey *string refresh = true } - if adminURL != "" && (config.AdminURL == nil || config.AdminURL.String() != adminURL) { + if input.AdminURL != "" && (config.AdminURL == nil || config.AdminURL.String() != input.AdminURL) { log.Infof("new Admin Panel URL provided, updated to %s (old value %s)", - adminURL, config.AdminURL) - newURL, err := ParseURL("Admin Panel URL", adminURL) + input.AdminURL, config.AdminURL) + newURL, err := ParseURL("Admin Panel URL", input.AdminURL) if err != nil { return nil, err } @@ -162,10 +170,10 @@ func ReadConfig(managementURL, adminURL, configPath string, preSharedKey *string refresh = true } - if preSharedKey != nil && config.PreSharedKey != *preSharedKey { + if input.PreSharedKey != nil && config.PreSharedKey != *input.PreSharedKey { log.Infof("new pre-shared key provided, updated to %s (old value %s)", - *preSharedKey, config.PreSharedKey) - config.PreSharedKey = *preSharedKey + *input.PreSharedKey, config.PreSharedKey) + config.PreSharedKey = *input.PreSharedKey refresh = true } if config.SSHKey == "" { @@ -184,7 +192,7 @@ func ReadConfig(managementURL, adminURL, configPath string, preSharedKey *string if refresh { // since we have new management URL, we need to update config file - if err := util.WriteJson(configPath, config); err != nil { + if err := util.WriteJson(input.ConfigPath, config); err != nil { return nil, err } } @@ -193,17 +201,16 @@ func ReadConfig(managementURL, adminURL, configPath string, preSharedKey *string } // GetConfig reads existing config or generates a new one -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, adminURL, configPath, preSharedKey) +func GetConfig(input ConfigInput) (*Config, error) { + if _, err := os.Stat(input.ConfigPath); os.IsNotExist(err) { + log.Infof("generating new config %s", input.ConfigPath) + return createNewConfig(input) } else { // don't overwrite pre-shared key if we receive asterisks from UI - pk := &preSharedKey - if preSharedKey == "**********" { - pk = nil + if *input.PreSharedKey == "**********" { + input.PreSharedKey = nil } - return ReadConfig(managementURL, adminURL, configPath, pk) + return ReadConfig(input) } } diff --git a/client/internal/config_test.go b/client/internal/config_test.go index a9cd3e88b..d4bf8433e 100644 --- a/client/internal/config_test.go +++ b/client/internal/config_test.go @@ -20,7 +20,12 @@ func TestGetConfig(t *testing.T) { preSharedKey := "preSharedKey" // case 1: new config has to be generated - config, err := GetConfig(managementURL, adminURL, path, preSharedKey) + config, err := GetConfig(ConfigInput{ + ManagementURL: managementURL, + AdminURL: adminURL, + ConfigPath: path, + PreSharedKey: &preSharedKey, + }) if err != nil { return } @@ -33,7 +38,12 @@ func TestGetConfig(t *testing.T) { } // case 2: existing config -> fetch it - config, err = GetConfig(managementURL, adminURL, path, preSharedKey) + config, err = GetConfig(ConfigInput{ + ManagementURL: managementURL, + AdminURL: adminURL, + ConfigPath: path, + PreSharedKey: &preSharedKey, + }) if err != nil { return } @@ -43,7 +53,12 @@ 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, adminURL, path, preSharedKey) + config, err = GetConfig(ConfigInput{ + ManagementURL: newManagementURL, + AdminURL: adminURL, + ConfigPath: path, + PreSharedKey: &preSharedKey, + }) if err != nil { return } diff --git a/client/internal/connect.go b/client/internal/connect.go index c13df0888..9e5566175 100644 --- a/client/internal/connect.go +++ b/client/internal/connect.go @@ -306,7 +306,10 @@ func UpdateOldManagementPort(ctx context.Context, config *Config, configPath str } // everything is alright => update the config - newConfig, err := ReadConfig(newURL.String(), "", configPath, nil) + newConfig, err := ReadConfig(ConfigInput{ + ManagementURL: newURL.String(), + ConfigPath: configPath, + }) if err != nil { log.Infof("couldn't switch to the new Management %s", newURL.String()) return config, fmt.Errorf("failed updating config file: %v", err) diff --git a/client/server/server.go b/client/server/server.go index a5fb3423b..4e07bcfa8 100644 --- a/client/server/server.go +++ b/client/server/server.go @@ -78,9 +78,17 @@ func (s *Server) Start() error { // if configuration exists, we just start connections. if is new config we skip and set status NeedsLogin // on failure we return error to retry - config, err := internal.ReadConfig(s.managementURL, s.adminURL, s.configPath, nil) + config, err := internal.ReadConfig(internal.ConfigInput{ + ManagementURL: s.managementURL, + AdminURL: s.adminURL, + ConfigPath: s.configPath, + }) if errorStatus, ok := gstatus.FromError(err); ok && errorStatus.Code() == codes.NotFound { - config, err = internal.GetConfig(s.managementURL, s.adminURL, s.configPath, "") + config, err = internal.GetConfig(internal.ConfigInput{ + ManagementURL: s.managementURL, + AdminURL: s.adminURL, + ConfigPath: s.configPath, + }) if err != nil { log.Warnf("unable to create configuration file: %v", err) return err @@ -165,7 +173,12 @@ func (s *Server) Login(callerCtx context.Context, msg *proto.LoginRequest) (*pro } s.mutex.Unlock() - config, err := internal.GetConfig(managementURL, adminURL, s.configPath, msg.PreSharedKey) + config, err := internal.GetConfig(internal.ConfigInput{ + ManagementURL: managementURL, + AdminURL: adminURL, + ConfigPath: s.configPath, + PreSharedKey: &msg.PreSharedKey, + }) if err != nil { return nil, err }