aboutsummaryrefslogtreecommitdiffstats
path: root/client/go
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2024-06-19 13:16:06 +0200
committerMartin Polden <mpolden@mpolden.no>2024-06-19 14:49:07 +0200
commitebf502ed704dcbf14a4b4c3661b15af5bc64ddb6 (patch)
treee25964e12d6a72411cbfb94621776e667e6e1f33 /client/go
parent21994d15f12d5632a8ac2169821fa1950ac67215 (diff)
Skip strict certificate requirement in CI environments
Diffstat (limited to 'client/go')
-rw-r--r--client/go/internal/cli/cmd/cert.go9
-rw-r--r--client/go/internal/cli/cmd/deploy_test.go11
-rw-r--r--client/go/internal/cli/cmd/prod_test.go24
3 files changed, 36 insertions, 8 deletions
diff --git a/client/go/internal/cli/cmd/cert.go b/client/go/internal/cli/cmd/cert.go
index 24b414443a0..9e0b8f6805c 100644
--- a/client/go/internal/cli/cmd/cert.go
+++ b/client/go/internal/cli/cmd/cert.go
@@ -179,13 +179,16 @@ func requireCertificate(force, ignoreZip bool, cli *CLI, target vespa.Target, pk
if err != nil {
return err
}
- if len(tlsOptions.CertificatePEM) == 0 {
- return errHint(fmt.Errorf("no certificate exists for %s", target.Deployment().Application.String()), "Try (re)creating the certificate with 'vespa auth cert'")
- }
if force {
return copyCertificate(tlsOptions, cli, pkg)
}
if pkg.HasCertificate() {
+ if cli.isCI() {
+ return nil // A matching certificate is not required in CI environments
+ }
+ if len(tlsOptions.CertificatePEM) == 0 {
+ return errHint(fmt.Errorf("no certificate exists for %s", target.Deployment().Application.String()), "Try (re)creating the certificate with 'vespa auth cert'")
+ }
matches, err := pkg.HasMatchingCertificate(tlsOptions.CertificatePEM)
if err != nil {
return err
diff --git a/client/go/internal/cli/cmd/deploy_test.go b/client/go/internal/cli/cmd/deploy_test.go
index b8a684cf1cf..6becef5b11a 100644
--- a/client/go/internal/cli/cmd/deploy_test.go
+++ b/client/go/internal/cli/cmd/deploy_test.go
@@ -24,7 +24,7 @@ func TestDeployCloud(t *testing.T) {
pkgDir := filepath.Join(t.TempDir(), "app")
createApplication(t, pkgDir, false, false)
- cli, stdout, stderr := newTestCLI(t, "CI=true", "NO_COLOR=true")
+ cli, stdout, stderr := newTestCLI(t, "NO_COLOR=true")
httpClient := &mock.HTTPClient{}
httpClient.NextResponseString(200, `ok`)
cli.httpClient = httpClient
@@ -37,11 +37,12 @@ func TestDeployCloud(t *testing.T) {
stderr.Reset()
require.NotNil(t, cli.Run("deploy", pkgDir))
+ apiKeyWarning := "Warning: Authenticating with API key, intended for use in CI environments.\nHint: Authenticate with 'vespa auth login' instead\n"
certError := `Error: deployment to Vespa Cloud requires certificate in application package
Hint: See https://cloud.vespa.ai/en/security/guide
Hint: Pass --add-cert to use the certificate of the current application
`
- assert.Equal(t, certError, stderr.String())
+ assert.Equal(t, apiKeyWarning+certError, stderr.String())
require.Nil(t, cli.Run("deploy", "--add-cert", "--wait=0", pkgDir))
assert.Contains(t, stdout.String(), "Success: Triggered deployment")
@@ -57,7 +58,7 @@ Hint: Pass --add-cert to use the certificate of the current application
buf.WriteString("wat\nthe\nfck\nn\n")
cli.Stdin = &buf
require.NotNil(t, cli.Run("deploy", "--add-cert=false", "--wait=0", pkgDir2))
- warning := "Warning: Application package does not contain security/clients.pem, which is required for deployments to Vespa Cloud\n"
+ warning := apiKeyWarning + "Warning: Application package does not contain security/clients.pem, which is required for deployments to Vespa Cloud\n"
assert.Equal(t, warning+strings.Repeat("Error: please answer 'y' or 'n'\n", 3)+certError, stderr.String())
buf.WriteString("y\n")
require.Nil(t, cli.Run("deploy", "--add-cert=false", "--wait=0", pkgDir2))
@@ -66,14 +67,14 @@ Hint: Pass --add-cert to use the certificate of the current application
// Missing application certificate is detected
stderr.Reset()
require.NotNil(t, cli.Run("deploy", "--application=t1.a2.i2", pkgDir2))
- assert.Equal(t, "Error: no certificate exists for t1.a2.i2\nHint: Try (re)creating the certificate with 'vespa auth cert'\n", stderr.String())
+ assert.Equal(t, apiKeyWarning+"Error: no certificate exists for t1.a2.i2\nHint: Try (re)creating the certificate with 'vespa auth cert'\n", stderr.String())
// Mismatching certificate is detected
stdout.Reset()
stderr.Reset()
assert.Nil(t, cli.Run("auth", "cert", "--application=t1.a1.i1", "-f", "--no-add"))
require.NotNil(t, cli.Run("deploy", "--application=t1.a1.i1", pkgDir2))
- assert.Equal(t, `Error: certificate in security/clients.pem does not match the stored key pair for t1.a1.i1
+ assert.Equal(t, apiKeyWarning+`Error: certificate in security/clients.pem does not match the stored key pair for t1.a1.i1
Hint: If this application was deployed using a different application ID in the past, the matching key pair may be stored under a different ID in `+
cli.config.homeDir+"\nHint: Specify the matching application with --application, or add the current certificate to the package using --add-cert\n",
stderr.String())
diff --git a/client/go/internal/cli/cmd/prod_test.go b/client/go/internal/cli/cmd/prod_test.go
index e2b0b3b88de..8ea20b3bbe5 100644
--- a/client/go/internal/cli/cmd/prod_test.go
+++ b/client/go/internal/cli/cmd/prod_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"github.com/vespa-engine/vespa/client/go/internal/ioutil"
"github.com/vespa-engine/vespa/client/go/internal/mock"
"github.com/vespa-engine/vespa/client/go/internal/vespa"
@@ -157,6 +158,29 @@ func TestProdDeploy(t *testing.T) {
prodDeploy(pkgDir, t)
}
+func TestProdDeployWithoutCertificate(t *testing.T) {
+ pkgDir := filepath.Join(t.TempDir(), "app")
+ createApplication(t, pkgDir, false, false)
+
+ httpClient := &mock.HTTPClient{}
+ cli, stdout, _ := newTestCLI(t, "CI=true")
+ cli.httpClient = httpClient
+ app := vespa.ApplicationID{Tenant: "t1", Application: "a1", Instance: "i1"}
+ assert.Nil(t, cli.Run("config", "set", "application", app.String()))
+ assert.Nil(t, cli.Run("config", "set", "target", "cloud"))
+ assert.Nil(t, cli.Run("auth", "api-key"))
+ stdout.Reset()
+ cli.Environment["VESPA_CLI_API_KEY_FILE"] = filepath.Join(cli.config.homeDir, "t1.api-key.pem")
+
+ // We have clients.pem, but no key pair for the application
+ require.Nil(t, os.MkdirAll(filepath.Join(pkgDir, "security"), 0755))
+ require.Nil(t, os.WriteFile(filepath.Join(pkgDir, "security", "clients.pem"), []byte{}, 0644))
+ httpClient.NextResponseString(200, `{"build": 42}`)
+ assert.Nil(t, cli.Run("prod", "deploy", pkgDir))
+ assert.Contains(t, stdout.String(), "Success: Deployed '"+pkgDir+"' with build number 42")
+ assert.Contains(t, stdout.String(), "See https://console.vespa-cloud.com/tenant/t1/application/a1/prod/deployment for deployment progress")
+}
+
func TestProdDeployWithoutTests(t *testing.T) {
pkgDir := filepath.Join(t.TempDir(), "app")
createApplication(t, pkgDir, false, true)