diff options
author | Martin Polden <mpolden@mpolden.no> | 2021-09-10 08:39:08 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2021-09-10 13:01:21 +0200 |
commit | 752bfd9eb3750383470013b146ae7afbcd972f30 (patch) | |
tree | 2d491f61696df85a8b754ce295b3d9ea559116ba /client | |
parent | 0f5f6a0bfa998c476db66c2c9dae39441810c4b9 (diff) |
Refactor configuration
Diffstat (limited to 'client')
-rw-r--r-- | client/go/cmd/api_key.go | 12 | ||||
-rw-r--r-- | client/go/cmd/api_key_test.go | 8 | ||||
-rw-r--r-- | client/go/cmd/cert.go | 24 | ||||
-rw-r--r-- | client/go/cmd/cert_test.go | 17 | ||||
-rw-r--r-- | client/go/cmd/command_tester.go | 12 | ||||
-rw-r--r-- | client/go/cmd/config.go | 162 | ||||
-rw-r--r-- | client/go/cmd/config_test.go | 34 | ||||
-rw-r--r-- | client/go/cmd/deploy.go | 61 | ||||
-rw-r--r-- | client/go/cmd/deploy_test.go | 11 | ||||
-rw-r--r-- | client/go/cmd/helpers.go | 48 | ||||
-rw-r--r-- | client/go/cmd/root.go | 1 | ||||
-rw-r--r-- | client/go/vespa/deploy.go | 2 |
12 files changed, 233 insertions, 159 deletions
diff --git a/client/go/cmd/api_key.go b/client/go/cmd/api_key.go index c94faa0d5e3..90cbdbc5bc1 100644 --- a/client/go/cmd/api_key.go +++ b/client/go/cmd/api_key.go @@ -7,7 +7,6 @@ import ( "fmt" "io/ioutil" "log" - "path/filepath" "github.com/spf13/cobra" "github.com/vespa-engine/vespa/client/go/util" @@ -29,16 +28,17 @@ var apiKeyCmd = &cobra.Command{ DisableAutoGenTag: true, Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { - configDir := configDir("") - if configDir == "" { - return - } app, err := vespa.ApplicationFromString(getApplication()) if err != nil { fatalErr(err, "Could not parse application") return } - apiKeyFile := filepath.Join(configDir, app.Tenant+".api-key.pem") + cfg, err := LoadConfig() + if err != nil { + fatalErr(err, "Could not load config") + return + } + apiKeyFile := cfg.APIKeyPath(app.Tenant) if util.PathExists(apiKeyFile) && !overwriteKey { printErrHint(fmt.Errorf("File %s already exists", apiKeyFile), "Use -f to overwrite it") printPublicKey(apiKeyFile, app.Tenant) diff --git a/client/go/cmd/api_key_test.go b/client/go/cmd/api_key_test.go index 0e50fd6d669..c00f520aa25 100644 --- a/client/go/cmd/api_key_test.go +++ b/client/go/cmd/api_key_test.go @@ -11,13 +11,13 @@ import ( ) func TestAPIKey(t *testing.T) { - configDir := t.TempDir() - keyFile := configDir + "/.vespa/t1.api-key.pem" + homeDir := t.TempDir() + keyFile := homeDir + "/.vespa/t1.api-key.pem" - out := execute(command{args: []string{"api-key", "-a", "t1.a1.i1"}, configDir: configDir}, t, nil) + out := execute(command{args: []string{"api-key", "-a", "t1.a1.i1"}, homeDir: homeDir}, t, nil) assert.True(t, strings.HasPrefix(out, "Success: API private key written to "+keyFile+"\n")) - out = execute(command{args: []string{"api-key", "-a", "t1.a1.i1"}, configDir: configDir}, t, nil) + out = execute(command{args: []string{"api-key", "-a", "t1.a1.i1"}, homeDir: homeDir}, t, nil) assert.True(t, strings.HasPrefix(out, "Error: File "+keyFile+" already exists\nHint: Use -f to overwrite it\n")) assert.True(t, strings.Contains(out, "This is your public key")) } diff --git a/client/go/cmd/cert.go b/client/go/cmd/cert.go index e1e11b6f73e..078c0704f9d 100644 --- a/client/go/cmd/cert.go +++ b/client/go/cmd/cert.go @@ -28,20 +28,34 @@ var certCmd = &cobra.Command{ DisableAutoGenTag: true, Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - app := getApplication() + app, err := vespa.ApplicationFromString(getApplication()) + if err != nil { + fatalErr(err) + return + } pkg, err := vespa.ApplicationPackageFrom(applicationSource(args)) if err != nil { fatalErr(err) return } - configDir := configDir(app) - if configDir == "" { + cfg, err := LoadConfig() + if err != nil { + fatalErr(err) return } securityDir := filepath.Join(pkg.Path, "security") pkgCertificateFile := filepath.Join(securityDir, "clients.pem") - privateKeyFile := filepath.Join(configDir, "data-plane-private-key.pem") - certificateFile := filepath.Join(configDir, "data-plane-public-cert.pem") + privateKeyFile, err := cfg.PrivateKeyPath(app) + if err != nil { + fatalErr(err) + return + } + certificateFile, err := cfg.CertificatePath(app) + if err != nil { + fatalErr(err) + return + } + if !overwriteCertificate { for _, file := range []string{pkgCertificateFile, privateKeyFile, certificateFile} { if util.PathExists(file) { diff --git a/client/go/cmd/cert_test.go b/client/go/cmd/cert_test.go index e655f76b0f1..174b5fe5e9d 100644 --- a/client/go/cmd/cert_test.go +++ b/client/go/cmd/cert_test.go @@ -11,20 +11,23 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/vespa-engine/vespa/client/go/vespa" ) func TestCert(t *testing.T) { - tmpDir := t.TempDir() - mockApplicationPackage(t, tmpDir) - out := execute(command{args: []string{"cert", "-a", "t1.a1.i1", tmpDir}, configDir: tmpDir}, t, nil) + homeDir := t.TempDir() + mockApplicationPackage(t, homeDir) + out := execute(command{args: []string{"cert", "-a", "t1.a1.i1", homeDir}, homeDir: homeDir}, t, nil) - pkgCertificate := filepath.Join(tmpDir, "security", "clients.pem") - certificate := filepath.Join(tmpDir, ".vespa", "t1.a1.i1", "data-plane-public-cert.pem") - privateKey := filepath.Join(tmpDir, ".vespa", "t1.a1.i1", "data-plane-private-key.pem") + app, err := vespa.ApplicationFromString("t1.a1.i1") + assert.Nil(t, err) + pkgCertificate := filepath.Join(homeDir, "security", "clients.pem") + certificate := filepath.Join(homeDir, ".vespa", app.String(), "data-plane-public-cert.pem") + privateKey := filepath.Join(homeDir, ".vespa", app.String(), "data-plane-private-key.pem") assert.Equal(t, fmt.Sprintf("Success: Certificate written to %s\nSuccess: Certificate written to %s\nSuccess: Private key written to %s\n", pkgCertificate, certificate, privateKey), out) - out = execute(command{args: []string{"cert", "-a", "t1.a1.i1", tmpDir}, configDir: tmpDir}, t, nil) + out = execute(command{args: []string{"cert", "-a", "t1.a1.i1", homeDir}, homeDir: homeDir}, t, nil) assert.True(t, strings.HasPrefix(out, "Error: Certificate or private key")) } diff --git a/client/go/cmd/command_tester.go b/client/go/cmd/command_tester.go index 42befbfb795..095a1af7ac3 100644 --- a/client/go/cmd/command_tester.go +++ b/client/go/cmd/command_tester.go @@ -24,9 +24,9 @@ import ( ) type command struct { - configDir string - args []string - moreArgs []string + homeDir string + args []string + moreArgs []string } func execute(cmd command, t *testing.T, client *mockHttpClient) string { @@ -38,11 +38,11 @@ func execute(cmd command, t *testing.T, client *mockHttpClient) string { color = aurora.NewAurora(false) // Set config dir. Use a separate one per test if none is specified - if cmd.configDir == "" { - cmd.configDir = t.TempDir() + if cmd.homeDir == "" { + cmd.homeDir = t.TempDir() viper.Reset() } - os.Setenv("VESPA_CLI_HOME", filepath.Join(cmd.configDir, ".vespa")) + os.Setenv("VESPA_CLI_HOME", filepath.Join(cmd.homeDir, ".vespa")) // Reset flags to their default value - persistent flags in Cobra persists over tests rootCmd.Flags().VisitAll(func(f *pflag.Flag) { diff --git a/client/go/cmd/config.go b/client/go/cmd/config.go index af62b2509d2..262f5d584b4 100644 --- a/client/go/cmd/config.go +++ b/client/go/cmd/config.go @@ -6,6 +6,7 @@ package cmd import ( "fmt" + "io/ioutil" "log" "os" "path/filepath" @@ -49,10 +50,17 @@ var setConfigCmd = &cobra.Command{ DisableAutoGenTag: true, Args: cobra.ExactArgs(2), Run: func(cmd *cobra.Command, args []string) { - if err := setOption(args[0], args[1]); err != nil { - log.Print(err) + cfg, err := LoadConfig() + if err != nil { + fatalErr(err, "Could not load config") + return + } + if err := cfg.Set(args[0], args[1]); err != nil { + fatalErr(err) } else { - writeConfig() + if err := cfg.Write(); err != nil { + fatalErr(err) + } } }, } @@ -64,70 +72,121 @@ var getConfigCmd = &cobra.Command{ Args: cobra.MaximumNArgs(1), DisableAutoGenTag: true, Run: func(cmd *cobra.Command, args []string) { + cfg, err := LoadConfig() + if err != nil { + fatalErr(err, "Could not load config") + return + } + if len(args) == 0 { // Print all values - printOption(targetFlag) - printOption(applicationFlag) + printOption(cfg, targetFlag) + printOption(cfg, applicationFlag) } else { - printOption(args[0]) + printOption(cfg, args[0]) } }, } -func printOption(option string) { - value, err := getOption(option) - if err != nil { - value = color.Faint("<unset>").String() - } else { - value = color.Cyan(value).String() - } - log.Printf("%s = %s", option, value) +type Config struct { + Home string + createDirs bool } -func configDir(application string) string { +func LoadConfig() (*Config, error) { home := os.Getenv("VESPA_CLI_HOME") if home == "" { var err error home, err = os.UserHomeDir() if err != nil { - fatalErr(err, "Could not determine configuration directory") - return "" + return nil, err } home = filepath.Join(home, ".vespa") } - configDir := filepath.Join(home, application) - if err := os.MkdirAll(configDir, 0755); err != nil { - fatalErr(err, "Could not create config directory") - return "" + if err := os.MkdirAll(home, 0700); err != nil { + return nil, err } - return configDir + c := &Config{Home: home, createDirs: true} + if err := c.load(); err != nil { + return nil, err + } + return c, nil } -func bindFlagToConfig(option string, command *cobra.Command) { - flagToConfigBindings[option] = command +func (c *Config) Write() error { + if err := os.MkdirAll(c.Home, 0700); err != nil { + return err + } + configFile := filepath.Join(c.Home, configName+"."+configType) + if !util.PathExists(configFile) { + if _, err := os.Create(configFile); err != nil { + return err + } + } + return viper.WriteConfig() +} + +func (c *Config) CertificatePath(app vespa.ApplicationID) (string, error) { + return c.applicationFilePath(app, "data-plane-public-cert.pem") +} + +func (c *Config) PrivateKeyPath(app vespa.ApplicationID) (string, error) { + return c.applicationFilePath(app, "data-plane-private-key.pem") +} + +func (c *Config) APIKeyPath(tenantName string) string { + return filepath.Join(c.Home, tenantName+".api-key.pem") +} + +func (c *Config) ReadAPIKey(tenantName string) ([]byte, error) { + return ioutil.ReadFile(c.APIKeyPath(tenantName)) } -func readConfig() { - configDir := configDir("") - if configDir == "" { - return +func (c *Config) ReadSessionID(app vespa.ApplicationID) (int64, error) { + sessionPath, err := c.applicationFilePath(app, "session_id") + if err != nil { + return 0, err + } + b, err := ioutil.ReadFile(sessionPath) + if err != nil { + return 0, err } + return strconv.ParseInt(strings.TrimSpace(string(b)), 10, 64) +} + +func (c *Config) WriteSessionID(app vespa.ApplicationID, sessionID int64) error { + sessionPath, err := c.applicationFilePath(app, "session_id") + if err != nil { + return err + } + return ioutil.WriteFile(sessionPath, []byte(fmt.Sprintf("%d\n", sessionID)), 0600) +} + +func (c *Config) applicationFilePath(app vespa.ApplicationID, name string) (string, error) { + appDir := filepath.Join(c.Home, app.String()) + if c.createDirs { + if err := os.MkdirAll(appDir, 0700); err != nil { + return "", err + } + } + return filepath.Join(appDir, name), nil +} + +func (c *Config) load() error { viper.SetConfigName(configName) viper.SetConfigType(configType) - viper.AddConfigPath(configDir) + viper.AddConfigPath(c.Home) viper.AutomaticEnv() for option, command := range flagToConfigBindings { viper.BindPFlag(option, command.PersistentFlags().Lookup(option)) } err := viper.ReadInConfig() if _, ok := err.(viper.ConfigFileNotFoundError); ok { - return // Fine - } - if err != nil { - fatalErr(err, "Could not read configuration") + return nil } + return err } -func getOption(option string) (string, error) { +func (c *Config) Get(option string) (string, error) { value := viper.GetString(option) if value == "" { return "", fmt.Errorf("no such option: %q", option) @@ -135,7 +194,7 @@ func getOption(option string) (string, error) { return value, nil } -func setOption(option, value string) error { +func (c *Config) Set(option, value string) error { switch option { case targetFlag: switch value { @@ -163,29 +222,16 @@ func setOption(option, value string) error { return fmt.Errorf("invalid option or value: %q: %q", option, value) } -func writeConfig() { - configDir := configDir("") - if configDir == "" { - return - } - - if !util.PathExists(configDir) { - if err := os.MkdirAll(configDir, 0700); err != nil { - fatalErr(err, "Could not create ", color.Cyan(configDir)) - return - } - } - - configFile := filepath.Join(configDir, configName+"."+configType) - if !util.PathExists(configFile) { - if _, err := os.Create(configFile); err != nil { - fatalErr(err, "Could not create ", color.Cyan(configFile)) - return - } +func printOption(cfg *Config, option string) { + value, err := cfg.Get(option) + if err != nil { + value = color.Faint("<unset>").String() + } else { + value = color.Cyan(value).String() } + log.Printf("%s = %s", option, value) +} - if err := viper.WriteConfig(); err != nil { - fatalErr(err, "Could not write config") - return - } +func bindFlagToConfig(option string, command *cobra.Command) { + flagToConfigBindings[option] = command } diff --git a/client/go/cmd/config_test.go b/client/go/cmd/config_test.go index dee63bcb58f..07d165d58e0 100644 --- a/client/go/cmd/config_test.go +++ b/client/go/cmd/config_test.go @@ -7,24 +7,24 @@ import ( ) func TestConfig(t *testing.T) { - configDir := t.TempDir() - assert.Equal(t, "invalid option or value: \"foo\": \"bar\"\n", execute(command{configDir: configDir, args: []string{"config", "set", "foo", "bar"}}, t, nil)) - assert.Equal(t, "foo = <unset>\n", execute(command{configDir: configDir, args: []string{"config", "get", "foo"}}, t, nil)) - assert.Equal(t, "target = local\n", execute(command{configDir: configDir, args: []string{"config", "get", "target"}}, t, nil)) - assert.Equal(t, "", execute(command{configDir: configDir, args: []string{"config", "set", "target", "cloud"}}, t, nil)) - assert.Equal(t, "target = cloud\n", execute(command{configDir: configDir, args: []string{"config", "get", "target"}}, t, nil)) - assert.Equal(t, "", execute(command{configDir: configDir, args: []string{"config", "set", "target", "http://127.0.0.1:8080"}}, t, nil)) - assert.Equal(t, "", execute(command{configDir: configDir, args: []string{"config", "set", "target", "https://127.0.0.1"}}, t, nil)) - assert.Equal(t, "target = https://127.0.0.1\n", execute(command{configDir: configDir, args: []string{"config", "get", "target"}}, t, nil)) + homeDir := t.TempDir() + assert.Equal(t, "invalid option or value: \"foo\": \"bar\"\n", execute(command{homeDir: homeDir, args: []string{"config", "set", "foo", "bar"}}, t, nil)) + assert.Equal(t, "foo = <unset>\n", execute(command{homeDir: homeDir, args: []string{"config", "get", "foo"}}, t, nil)) + assert.Equal(t, "target = local\n", execute(command{homeDir: homeDir, args: []string{"config", "get", "target"}}, t, nil)) + assert.Equal(t, "", execute(command{homeDir: homeDir, args: []string{"config", "set", "target", "cloud"}}, t, nil)) + assert.Equal(t, "target = cloud\n", execute(command{homeDir: homeDir, args: []string{"config", "get", "target"}}, t, nil)) + assert.Equal(t, "", execute(command{homeDir: homeDir, args: []string{"config", "set", "target", "http://127.0.0.1:8080"}}, t, nil)) + assert.Equal(t, "", execute(command{homeDir: homeDir, args: []string{"config", "set", "target", "https://127.0.0.1"}}, t, nil)) + assert.Equal(t, "target = https://127.0.0.1\n", execute(command{homeDir: homeDir, args: []string{"config", "get", "target"}}, t, nil)) - assert.Equal(t, "invalid application: \"foo\"\n", execute(command{configDir: configDir, args: []string{"config", "set", "application", "foo"}}, t, nil)) - assert.Equal(t, "application = <unset>\n", execute(command{configDir: configDir, args: []string{"config", "get", "application"}}, t, nil)) - assert.Equal(t, "", execute(command{configDir: configDir, args: []string{"config", "set", "application", "t1.a1.i1"}}, t, nil)) - assert.Equal(t, "application = t1.a1.i1\n", execute(command{configDir: configDir, args: []string{"config", "get", "application"}}, t, nil)) + assert.Equal(t, "invalid application: \"foo\"\n", execute(command{homeDir: homeDir, args: []string{"config", "set", "application", "foo"}}, t, nil)) + assert.Equal(t, "application = <unset>\n", execute(command{homeDir: homeDir, args: []string{"config", "get", "application"}}, t, nil)) + assert.Equal(t, "", execute(command{homeDir: homeDir, args: []string{"config", "set", "application", "t1.a1.i1"}}, t, nil)) + assert.Equal(t, "application = t1.a1.i1\n", execute(command{homeDir: homeDir, args: []string{"config", "get", "application"}}, t, nil)) - assert.Equal(t, "target = https://127.0.0.1\napplication = t1.a1.i1\n", execute(command{configDir: configDir, args: []string{"config", "get"}}, t, nil)) + assert.Equal(t, "target = https://127.0.0.1\napplication = t1.a1.i1\n", execute(command{homeDir: homeDir, args: []string{"config", "get"}}, t, nil)) - assert.Equal(t, "", execute(command{configDir: configDir, args: []string{"config", "set", "wait", "60"}}, t, nil)) - assert.Equal(t, "wait option must be an integer >= 0, got \"foo\"\n", execute(command{configDir: configDir, args: []string{"config", "set", "wait", "foo"}}, t, nil)) - assert.Equal(t, "wait = 60\n", execute(command{configDir: configDir, args: []string{"config", "get", "wait"}}, t, nil)) + assert.Equal(t, "", execute(command{homeDir: homeDir, args: []string{"config", "set", "wait", "60"}}, t, nil)) + assert.Equal(t, "wait option must be an integer >= 0, got \"foo\"\n", execute(command{homeDir: homeDir, args: []string{"config", "set", "wait", "foo"}}, t, nil)) + assert.Equal(t, "wait = 60\n", execute(command{homeDir: homeDir, args: []string{"config", "get", "wait"}}, t, nil)) } diff --git a/client/go/cmd/deploy.go b/client/go/cmd/deploy.go index 19fa08ebaa4..d2836a6bcd1 100644 --- a/client/go/cmd/deploy.go +++ b/client/go/cmd/deploy.go @@ -6,12 +6,7 @@ package cmd import ( "fmt" - "io/ioutil" "log" - "os" - "path/filepath" - "strconv" - "strings" "github.com/spf13/cobra" "github.com/vespa-engine/vespa/client/go/vespa" @@ -51,6 +46,11 @@ If application directory is not specified, it defaults to working directory.`, fatalErr(nil, err.Error()) return } + cfg, err := LoadConfig() + if err != nil { + fatalErr(err, "Could not load config") + return + } target := getTarget() opts := vespa.DeploymentOpts{ApplicationPackage: pkg, Target: target} if opts.IsCloud() { @@ -58,7 +58,11 @@ If application directory is not specified, it defaults to working directory.`, if !opts.ApplicationPackage.HasCertificate() { fatalErrHint(fmt.Errorf("Missing certificate in application package"), "Applications in Vespa Cloud require a certificate", "Try 'vespa cert'") } - opts.APIKey = readAPIKey(deployment.Application.Tenant) + opts.APIKey, err = cfg.ReadAPIKey(deployment.Application.Tenant) + if err != nil { + fatalErrHint(err, "Deployment to cloud requires an API key. Try 'vespa api-key'") + return + } opts.Deployment = deployment } if sessionOrRunID, err := vespa.Deploy(opts); err == nil { @@ -93,8 +97,9 @@ var prepareCmd = &cobra.Command{ fatalErr(err, "Could not find application package") return } - configDir := configDir("default") - if configDir == "" { + cfg, err := LoadConfig() + if err != nil { + fatalErr(err, "Could not load config") return } target := getTarget() @@ -103,7 +108,10 @@ var prepareCmd = &cobra.Command{ Target: target, }) if err == nil { - writeSessionID(configDir, sessionID) + if err := cfg.WriteSessionID(vespa.DefaultApplication, sessionID); err != nil { + fatalErr(err, "Could not write session ID") + return + } printSuccess("Prepared ", color.Cyan(pkg.Path), " with session ", sessionID) } else { fatalErr(nil, err.Error()) @@ -122,8 +130,16 @@ var activateCmd = &cobra.Command{ fatalErr(err, "Could not find application package") return } - configDir := configDir("default") - sessionID := readSessionID(configDir) + cfg, err := LoadConfig() + if err != nil { + fatalErr(err, "Could not load config") + return + } + sessionID, err := cfg.ReadSessionID(vespa.DefaultApplication) + if err != nil { + fatalErr(err, "Could not read session ID") + return + } target := getTarget() err = vespa.Activate(sessionID, vespa.DeploymentOpts{ ApplicationPackage: pkg, @@ -144,26 +160,3 @@ func waitForQueryService(sessionOrRunID int64) { waitForService("query", sessionOrRunID) } } - -func writeSessionID(appConfigDir string, sessionID int64) { - if err := os.MkdirAll(appConfigDir, 0755); err != nil { - fatalErr(err, "Could not create directory for session ID") - } - if err := ioutil.WriteFile(sessionIDFile(appConfigDir), []byte(fmt.Sprintf("%d\n", sessionID)), 0600); err != nil { - fatalErr(err, "Could not write session ID") - } -} - -func readSessionID(appConfigDir string) int64 { - b, err := ioutil.ReadFile(sessionIDFile(appConfigDir)) - if err != nil { - fatalErr(err, "Could not read session ID") - } - id, err := strconv.ParseInt(strings.TrimSpace(string(b)), 10, 64) - if err != nil { - fatalErr(err, "Invalid session ID") - } - return id -} - -func sessionIDFile(appConfigDir string) string { return filepath.Join(appConfigDir, "session_id") } diff --git a/client/go/cmd/deploy_test.go b/client/go/cmd/deploy_test.go index ff85cd3d835..f24ba0829f9 100644 --- a/client/go/cmd/deploy_test.go +++ b/client/go/cmd/deploy_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/vespa-engine/vespa/client/go/vespa" ) func TestPrepareZip(t *testing.T) { @@ -124,12 +125,14 @@ func assertPrepare(applicationPackage string, arguments []string, t *testing.T) func assertActivate(applicationPackage string, arguments []string, t *testing.T) { client := &mockHttpClient{} - configDir := t.TempDir() - appConfigDir := filepath.Join(configDir, ".vespa", "default") - writeSessionID(appConfigDir, 42) + homeDir := t.TempDir() + cfg := Config{Home: filepath.Join(homeDir, ".vespa"), createDirs: true} + if err := cfg.WriteSessionID(vespa.DefaultApplication, 42); err != nil { + t.Fatal(err) + } assert.Equal(t, "Success: Activated "+applicationPackage+" with session 42\n", - execute(command{args: arguments, configDir: configDir}, t, client)) + execute(command{args: arguments, homeDir: homeDir}, t, client)) url := "http://127.0.0.1:19071/application/v2/tenant/default/session/42/active" assert.Equal(t, url, client.lastRequest.URL.String()) assert.Equal(t, "PUT", client.lastRequest.Method) diff --git a/client/go/cmd/helpers.go b/client/go/cmd/helpers.go index b672419cae6..14699abf40e 100644 --- a/client/go/cmd/helpers.go +++ b/client/go/cmd/helpers.go @@ -10,7 +10,6 @@ import ( "io/ioutil" "log" "os" - "path/filepath" "strings" "time" @@ -51,16 +50,6 @@ func printSuccess(msg ...interface{}) { log.Print(color.Green("Success: "), fmt.Sprint(msg...)) } -func readAPIKey(tenant string) []byte { - configDir := configDir("") - apiKeyPath := filepath.Join(configDir, tenant+".api-key.pem") - key, err := ioutil.ReadFile(apiKeyPath) - if err != nil { - fatalErrHint(err, "Deployment to cloud requires an API key. Try 'vespa api-key'") - } - return key -} - func deploymentFromArgs() vespa.Deployment { zone, err := vespa.ZoneFromString(zoneArg) if err != nil { @@ -81,7 +70,12 @@ func applicationSource(args []string) string { } func getApplication() string { - app, err := getOption(applicationFlag) + cfg, err := LoadConfig() + if err != nil { + fatalErr(err, "Could not load config") + return "" + } + app, err := cfg.Get(applicationFlag) if err != nil { fatalErr(err, "A valid application must be specified") } @@ -89,7 +83,12 @@ func getApplication() string { } func getTargetType() string { - target, err := getOption(targetFlag) + cfg, err := LoadConfig() + if err != nil { + fatalErr(err, "Could not load config") + return "" + } + target, err := cfg.Get(targetFlag) if err != nil { fatalErr(err, "A valid target must be specified") } @@ -122,10 +121,25 @@ func getTarget() vespa.Target { return vespa.LocalTarget() case "cloud": deployment := deploymentFromArgs() - apiKey := readAPIKey(deployment.Application.Tenant) - configDir := configDir(deployment.Application.String()) - privateKeyFile := filepath.Join(configDir, "data-plane-private-key.pem") - certificateFile := filepath.Join(configDir, "data-plane-public-cert.pem") + cfg, err := LoadConfig() + if err != nil { + fatalErr(err, "Could not load config") + return nil + } + apiKey, err := ioutil.ReadFile(cfg.APIKeyPath(deployment.Application.Tenant)) + if err != nil { + fatalErrHint(err, "Deployment to cloud requires an API key. Try 'vespa api-key'") + } + privateKeyFile, err := cfg.PrivateKeyPath(deployment.Application) + if err != nil { + fatalErr(err) + return nil + } + certificateFile, err := cfg.CertificatePath(deployment.Application) + if err != nil { + fatalErr(err) + return nil + } kp, err := tls.LoadX509KeyPair(certificateFile, privateKeyFile) if err != nil { fatalErr(err, "Could not read key pair") diff --git a/client/go/cmd/root.go b/client/go/cmd/root.go index fde7d6edb5a..f8bf87b508c 100644 --- a/client/go/cmd/root.go +++ b/client/go/cmd/root.go @@ -49,7 +49,6 @@ func configureLogger() { func init() { configureLogger() - cobra.OnInitialize(readConfig) rootCmd.PersistentFlags().StringVarP(&targetArg, targetFlag, "t", "local", "The name or URL of the recipient of this command") rootCmd.PersistentFlags().StringVarP(&applicationArg, applicationFlag, "a", "", "The application to manage") rootCmd.PersistentFlags().IntVarP(&waitSecsArg, waitFlag, "w", 0, "Number of seconds to wait for a service to become ready") diff --git a/client/go/vespa/deploy.go b/client/go/vespa/deploy.go index 081e9fc17d2..22ab5380c23 100644 --- a/client/go/vespa/deploy.go +++ b/client/go/vespa/deploy.go @@ -23,6 +23,8 @@ import ( "github.com/vespa-engine/vespa/client/go/util" ) +var DefaultApplication = ApplicationID{Tenant: "default", Application: "application", Instance: "default"} + type ApplicationID struct { Tenant string Application string |