summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2022-06-30 09:59:20 +0200
committerMartin Polden <mpolden@mpolden.no>2022-06-30 11:18:16 +0200
commit270b58aadb6af7fdd9dcadd09ee517cdbf1f3e20 (patch)
tree2e3591a4ca2db48212269c81c294fdbd039cf512 /client
parent6aec45e781d9476b0288794bba543391b716d77b (diff)
Support specifying cluster name
Diffstat (limited to 'client')
-rw-r--r--client/go/cmd/config.go16
-rw-r--r--client/go/cmd/config_test.go6
-rw-r--r--client/go/cmd/curl.go2
-rw-r--r--client/go/cmd/curl_test.go1
-rw-r--r--client/go/cmd/deploy.go2
-rw-r--r--client/go/cmd/document.go2
-rw-r--r--client/go/cmd/query.go2
-rw-r--r--client/go/cmd/root.go7
-rw-r--r--client/go/cmd/status.go2
-rw-r--r--client/go/vespa/target_cloud.go30
10 files changed, 48 insertions, 22 deletions
diff --git a/client/go/cmd/config.go b/client/go/cmd/config.go
index b8a7cb9c24c..8f81f8e359f 100644
--- a/client/go/cmd/config.go
+++ b/client/go/cmd/config.go
@@ -62,6 +62,14 @@ and "hosted" targets. See https://cloud.vespa.ai/en/tenant-apps-instances for
more details. This has no default value. Examples: tenant1.app1,
tenant1.app1.instance1
+cluster
+
+Specifies the container cluster to manage. If left empty (default) and the
+application has only one container cluster, that cluster is chosen
+automatically. When an application has multiple cluster this must be set a
+valid cluster name, as specified in services.xml. See
+https://docs.vespa.ai/en/reference/services-container.html for more details.
+
color
Controls how Vespa CLI uses colors. Setting this to "auto" (default) enables
@@ -353,6 +361,11 @@ func (c *Config) application() (vespa.ApplicationID, error) {
return application, nil
}
+func (c *Config) cluster() string {
+ cluster, _ := c.get(clusterFlag)
+ return cluster
+}
+
func (c *Config) deploymentIn(system vespa.System) (vespa.Deployment, error) {
zone := system.DefaultZone
zoneName, ok := c.get(zoneFlag)
@@ -558,6 +571,9 @@ func (c *Config) set(option, value string) error {
case instanceFlag:
c.config.Set(option, value)
return nil
+ case clusterFlag:
+ c.config.Set(clusterFlag, value)
+ return nil
case waitFlag:
if n, err := strconv.Atoi(value); err != nil || n < 0 {
return fmt.Errorf("%s option must be an integer >= 0, got %q", option, value)
diff --git a/client/go/cmd/config_test.go b/client/go/cmd/config_test.go
index 86c7e2695fa..7d701931a04 100644
--- a/client/go/cmd/config_test.go
+++ b/client/go/cmd/config_test.go
@@ -35,6 +35,11 @@ func TestConfig(t *testing.T) {
assertConfigCommand(t, configHome, "", "config", "set", "application", "t1.a1")
assertConfigCommand(t, configHome, "application = t1.a1.default\n", "config", "get", "application")
+ // cluster
+ assertConfigCommand(t, configHome, "cluster = <unset>\n", "config", "get", "cluster")
+ assertConfigCommand(t, configHome, "", "config", "set", "cluster", "feed")
+ assertConfigCommand(t, configHome, "cluster = feed\n", "config", "get", "cluster")
+
// instance
assertConfigCommand(t, configHome, "instance = <unset>\n", "config", "get", "instance")
assertConfigCommand(t, configHome, "", "config", "set", "instance", "i2")
@@ -99,6 +104,7 @@ func TestLocalConfig(t *testing.T) {
// get merges settings from local and global config
assertConfigCommand(t, configHome, "", "config", "set", "--local", "application", "t1.a1")
assertConfigCommand(t, configHome, `application = t1.a1.default
+cluster = <unset>
color = auto
instance = foo
quiet = false
diff --git a/client/go/cmd/curl.go b/client/go/cmd/curl.go
index 41e37f5319b..4b2eb9ba987 100644
--- a/client/go/cmd/curl.go
+++ b/client/go/cmd/curl.go
@@ -38,7 +38,7 @@ $ vespa curl -- -v --data-urlencode "yql=select * from music where album contain
if err != nil {
return err
}
- service, err := target.Service(curlService, 0, 0, "")
+ service, err := target.Service(curlService, 0, 0, cli.config.cluster())
if err != nil {
return err
}
diff --git a/client/go/cmd/curl_test.go b/client/go/cmd/curl_test.go
index 520cf41e308..3eca0726bb4 100644
--- a/client/go/cmd/curl_test.go
+++ b/client/go/cmd/curl_test.go
@@ -14,6 +14,7 @@ func TestCurl(t *testing.T) {
cli.Environment["VESPA_CLI_ENDPOINTS"] = "{\"endpoints\":[{\"cluster\":\"container\",\"url\":\"http://127.0.0.1:8080\"}]}"
assert.Nil(t, cli.Run("config", "set", "application", "t1.a1.i1"))
assert.Nil(t, cli.Run("config", "set", "target", "cloud"))
+ assert.Nil(t, cli.Run("config", "set", "cluster", "container"))
assert.Nil(t, cli.Run("auth", "api-key"))
assert.Nil(t, cli.Run("auth", "cert", "--no-add"))
diff --git a/client/go/cmd/deploy.go b/client/go/cmd/deploy.go
index 930e25dddc7..e72667e49b6 100644
--- a/client/go/cmd/deploy.go
+++ b/client/go/cmd/deploy.go
@@ -178,7 +178,7 @@ func waitForQueryService(cli *CLI, target vespa.Target, sessionOrRunID int64) er
}
if timeout > 0 {
log.Println()
- _, err := cli.service(target, vespa.QueryService, sessionOrRunID, "")
+ _, err := cli.service(target, vespa.QueryService, sessionOrRunID, cli.config.cluster())
return err
}
return nil
diff --git a/client/go/cmd/document.go b/client/go/cmd/document.go
index 32648393492..b2f71121d1a 100644
--- a/client/go/cmd/document.go
+++ b/client/go/cmd/document.go
@@ -178,7 +178,7 @@ func documentService(cli *CLI) (*vespa.Service, error) {
if err != nil {
return nil, err
}
- return cli.service(target, vespa.DocumentService, 0, "")
+ return cli.service(target, vespa.DocumentService, 0, cli.config.cluster())
}
func operationOptions(stderr io.Writer, printCurl bool, timeoutSecs int) vespa.OperationOptions {
diff --git a/client/go/cmd/query.go b/client/go/cmd/query.go
index 82ff5185cbd..d147e986cec 100644
--- a/client/go/cmd/query.go
+++ b/client/go/cmd/query.go
@@ -62,7 +62,7 @@ func query(cli *CLI, arguments []string, timeoutSecs int, curl bool) error {
if err != nil {
return err
}
- service, err := cli.service(target, vespa.QueryService, 0, "")
+ service, err := cli.service(target, vespa.QueryService, 0, cli.config.cluster())
if err != nil {
return err
}
diff --git a/client/go/cmd/root.go b/client/go/cmd/root.go
index 461c2ea5bf0..e2f03cbc7ce 100644
--- a/client/go/cmd/root.go
+++ b/client/go/cmd/root.go
@@ -28,6 +28,7 @@ import (
const (
applicationFlag = "application"
instanceFlag = "instance"
+ clusterFlag = "cluster"
zoneFlag = "zone"
targetFlag = "target"
waitFlag = "wait"
@@ -178,14 +179,16 @@ func (c *CLI) configureFlags() map[string]*pflag.Flag {
target string
application string
instance string
+ cluster string
zone string
waitSecs int
color string
quiet bool
)
c.cmd.PersistentFlags().StringVarP(&target, targetFlag, "t", "local", `The target platform to use. Must be "local", "cloud", "hosted" or an URL`)
- c.cmd.PersistentFlags().StringVarP(&application, applicationFlag, "a", "", "The application to manage")
- c.cmd.PersistentFlags().StringVarP(&instance, instanceFlag, "i", "", "The instance of the application to manage")
+ c.cmd.PersistentFlags().StringVarP(&application, applicationFlag, "a", "", "The application to use")
+ c.cmd.PersistentFlags().StringVarP(&instance, instanceFlag, "i", "", "The instance of the application to use")
+ c.cmd.PersistentFlags().StringVarP(&cluster, clusterFlag, "C", "", "The container cluster to use. This is only required for applications with multiple clusters")
c.cmd.PersistentFlags().StringVarP(&zone, zoneFlag, "z", "", "The zone to use. This defaults to a dev zone")
c.cmd.PersistentFlags().IntVarP(&waitSecs, waitFlag, "w", 0, "Number of seconds to wait for a service to become ready")
c.cmd.PersistentFlags().StringVarP(&color, colorFlag, "c", "auto", `Whether to use colors in output. Must be "auto", "never", or "always"`)
diff --git a/client/go/cmd/status.go b/client/go/cmd/status.go
index 65da8f8f1c0..c44bbddb98a 100644
--- a/client/go/cmd/status.go
+++ b/client/go/cmd/status.go
@@ -81,7 +81,7 @@ func printServiceStatus(cli *CLI, name string) error {
if timeout > 0 {
log.Printf("Waiting up to %s for service to become ready ...", color.CyanString(timeout.String()))
}
- s, err := t.Service(name, timeout, 0, "")
+ s, err := t.Service(name, timeout, 0, cli.config.cluster())
if err != nil {
return err
}
diff --git a/client/go/vespa/target_cloud.go b/client/go/vespa/target_cloud.go
index 696d5109015..1076724a252 100644
--- a/client/go/vespa/target_cloud.go
+++ b/client/go/vespa/target_cloud.go
@@ -9,6 +9,7 @@ import (
"net/http"
"sort"
"strconv"
+ "strings"
"time"
"github.com/vespa-engine/vespa/client/go/auth/auth0"
@@ -82,28 +83,27 @@ func CloudTarget(httpClient util.HTTPClient, apiOptions APIOptions, deploymentOp
}, nil
}
-func (t *cloudTarget) resolveEndpoint(cluster string) (string, error) {
+func (t *cloudTarget) findClusterURL(cluster string) (string, error) {
+ clusters := make([]string, 0, len(t.deploymentOptions.ClusterURLs))
+ for c := range t.deploymentOptions.ClusterURLs {
+ clusters = append(clusters, c)
+ }
if cluster == "" {
- for _, u := range t.deploymentOptions.ClusterURLs {
+ for _, url := range t.deploymentOptions.ClusterURLs {
if len(t.deploymentOptions.ClusterURLs) == 1 {
- return u, nil
+ return url, nil
} else {
- return "", fmt.Errorf("multiple clusters, none chosen: %v", t.deploymentOptions.ClusterURLs)
+ return "", fmt.Errorf("no cluster specified: found multiple clusters '%s'", strings.Join(clusters, "', '"))
}
}
} else {
- u := t.deploymentOptions.ClusterURLs[cluster]
- if u == "" {
- clusters := make([]string, len(t.deploymentOptions.ClusterURLs))
- for c := range t.deploymentOptions.ClusterURLs {
- clusters = append(clusters, c)
- }
- return "", fmt.Errorf("unknown cluster '%s': must be one of %v", cluster, clusters)
+ url, ok := t.deploymentOptions.ClusterURLs[cluster]
+ if !ok {
+ return "", fmt.Errorf("invalid cluster '%s': must be one of '%s'", cluster, strings.Join(clusters, "', '"))
}
- return u, nil
+ return url, nil
}
-
- return "", fmt.Errorf("no endpoints")
+ return "", fmt.Errorf("no endpoints found")
}
func (t *cloudTarget) Type() string {
@@ -142,7 +142,7 @@ func (t *cloudTarget) Service(name string, timeout time.Duration, runID int64, c
return nil, err
}
}
- url, err := t.resolveEndpoint(cluster)
+ url, err := t.findClusterURL(cluster)
if err != nil {
return nil, err
}