aboutsummaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2023-07-17 14:45:27 +0200
committerMartin Polden <mpolden@mpolden.no>2023-07-17 15:10:53 +0200
commitf48dbf9e3938b938a21a9246dc50b3a19c020d18 (patch)
tree2719249a06c1e93c9bb05389931b4e4b10ef214c /client
parent96a788f1ec06d341479a603b3819eacfc98316ea (diff)
Require certificate files specified in environment
Diffstat (limited to 'client')
-rw-r--r--client/go/internal/cli/cmd/cert.go16
-rw-r--r--client/go/internal/cli/cmd/config.go70
-rw-r--r--client/go/internal/cli/cmd/config_test.go6
3 files changed, 58 insertions, 34 deletions
diff --git a/client/go/internal/cli/cmd/cert.go b/client/go/internal/cli/cmd/cert.go
index ccfce5eb7bb..f7320e37626 100644
--- a/client/go/internal/cli/cmd/cert.go
+++ b/client/go/internal/cli/cmd/cert.go
@@ -114,11 +114,11 @@ func doCert(cli *CLI, overwriteCertificate, skipApplicationPackage bool, args []
if !overwriteCertificate {
hint := "Use -f flag to force overwriting"
- if util.PathExists(privateKeyFile) {
- return errHint(fmt.Errorf("private key %s already exists", color.CyanString(privateKeyFile)), hint)
+ if util.PathExists(privateKeyFile.path) {
+ return errHint(fmt.Errorf("private key %s already exists", color.CyanString(privateKeyFile.path)), hint)
}
- if util.PathExists(certificateFile) {
- return errHint(fmt.Errorf("certificate %s already exists", color.CyanString(certificateFile)), hint)
+ if util.PathExists(certificateFile.path) {
+ return errHint(fmt.Errorf("certificate %s already exists", color.CyanString(certificateFile.path)), hint)
}
}
@@ -126,14 +126,14 @@ func doCert(cli *CLI, overwriteCertificate, skipApplicationPackage bool, args []
if err != nil {
return err
}
- if err := keyPair.WriteCertificateFile(certificateFile, overwriteCertificate); err != nil {
+ if err := keyPair.WriteCertificateFile(certificateFile.path, overwriteCertificate); err != nil {
return fmt.Errorf("could not write certificate: %w", err)
}
- if err := keyPair.WritePrivateKeyFile(privateKeyFile, overwriteCertificate); err != nil {
+ if err := keyPair.WritePrivateKeyFile(privateKeyFile.path, overwriteCertificate); err != nil {
return fmt.Errorf("could not write private key: %w", err)
}
- cli.printSuccess("Certificate written to ", color.CyanString(certificateFile))
- cli.printSuccess("Private key written to ", color.CyanString(privateKeyFile))
+ cli.printSuccess("Certificate written to ", color.CyanString(certificateFile.path))
+ cli.printSuccess("Private key written to ", color.CyanString(privateKeyFile.path))
if !skipApplicationPackage {
return doCertAdd(cli, overwriteCertificate, args)
}
diff --git a/client/go/internal/cli/cmd/config.go b/client/go/internal/cli/cmd/config.go
index eb79a2004c4..0a03686dd33 100644
--- a/client/go/internal/cli/cmd/config.go
+++ b/client/go/internal/cli/cmd/config.go
@@ -384,24 +384,43 @@ func (c *Config) caCertificatePath() string {
return c.environment["VESPA_CLI_DATA_PLANE_CA_CERT_FILE"]
}
-func (c *Config) certificatePath(app vespa.ApplicationID, targetType string) (string, error) {
- if override, ok := c.environment["VESPA_CLI_DATA_PLANE_CERT_FILE"]; ok {
- return override, nil
- }
- if targetType == vespa.TargetHosted {
- return athenzPath("cert")
- }
- return c.applicationFilePath(app, "data-plane-public-cert.pem")
+type credentialsFile struct {
+ path string
+ optional bool
}
-func (c *Config) privateKeyPath(app vespa.ApplicationID, targetType string) (string, error) {
- if override, ok := c.environment["VESPA_CLI_DATA_PLANE_KEY_FILE"]; ok {
- return override, nil
+func (c *Config) credentialsFile(app vespa.ApplicationID, targetType string, cert bool) (credentialsFile, error) {
+ envVar := "VESPA_CLI_DATA_PLANE_CERT_FILE"
+ athenzFile := "cert"
+ applicationFile := "data-plane-public-cert.pem"
+ if !cert {
+ envVar = "VESPA_CLI_DATA_PLANE_KEY_FILE"
+ athenzFile = "key"
+ applicationFile = "data-plane-private-key.pem"
+ }
+ if override, ok := c.environment[envVar]; ok {
+ return credentialsFile{override, false}, nil
}
if targetType == vespa.TargetHosted {
- return athenzPath("key")
+ path, err := athenzPath(athenzFile)
+ if err != nil {
+ return credentialsFile{}, err
+ }
+ return credentialsFile{path, false}, nil
}
- return c.applicationFilePath(app, "data-plane-private-key.pem")
+ path, err := c.applicationFilePath(app, applicationFile)
+ if err != nil {
+ return credentialsFile{}, err
+ }
+ return credentialsFile{path, true}, nil
+}
+
+func (c *Config) certificatePath(app vespa.ApplicationID, targetType string) (credentialsFile, error) {
+ return c.credentialsFile(app, targetType, true)
+}
+
+func (c *Config) privateKeyPath(app vespa.ApplicationID, targetType string) (credentialsFile, error) {
+ return c.credentialsFile(app, targetType, false)
}
func (c *Config) readTLSOptions(app vespa.ApplicationID, targetType string) (vespa.TLSOptions, error) {
@@ -413,16 +432,13 @@ func (c *Config) readTLSOptions(app vespa.ApplicationID, targetType string) (ves
// CA certificate
if caCertOk {
options.CACertificate = []byte(caCertText)
- } else {
- caCertFile := c.caCertificatePath()
- if caCertFile != "" {
- b, err := os.ReadFile(caCertFile)
- if err != nil {
- return options, err
- }
- options.CACertificate = b
- options.CACertificateFile = caCertFile
+ } else if caCertFile := c.caCertificatePath(); caCertFile != "" {
+ b, err := os.ReadFile(caCertFile)
+ if err != nil {
+ return options, err
}
+ options.CACertificate = b
+ options.CACertificateFile = caCertFile
}
// Certificate and private key
if certOk && keyOk {
@@ -440,15 +456,17 @@ func (c *Config) readTLSOptions(app vespa.ApplicationID, targetType string) (ves
if err != nil {
return vespa.TLSOptions{}, err
}
- kp, err := tls.LoadX509KeyPair(certFile, keyFile)
+ kp, err := tls.LoadX509KeyPair(certFile.path, keyFile.path)
+ allowMissing := os.IsNotExist(err) && keyFile.optional && certFile.optional
if err == nil {
options.KeyPair = []tls.Certificate{kp}
- options.PrivateKeyFile = keyFile
- options.CertificateFile = certFile
- } else if err != nil && !os.IsNotExist(err) {
+ options.PrivateKeyFile = keyFile.path
+ options.CertificateFile = certFile.path
+ } else if err != nil && !allowMissing {
return vespa.TLSOptions{}, err
}
}
+ // If we found a key pair, parse it and check expiry
if options.KeyPair != nil {
cert, err := x509.ParseCertificate(options.KeyPair[0].Certificate[0])
if err != nil {
diff --git a/client/go/internal/cli/cmd/config_test.go b/client/go/internal/cli/cmd/config_test.go
index 14a3cf7cbbc..b00be38d021 100644
--- a/client/go/internal/cli/cmd/config_test.go
+++ b/client/go/internal/cli/cmd/config_test.go
@@ -253,6 +253,12 @@ func TestConfigReadTLSOptions(t *testing.T) {
PrivateKeyFile: defaultKeyFile,
},
)
+
+ // Key pair files specified through environment are required
+ nonExistentFile := filepath.Join(homeDir, "non-existent-file")
+ cli, _, _ := newTestCLI(t, "VESPA_CLI_DATA_PLANE_CERT_FILE="+nonExistentFile, "VESPA_CLI_DATA_PLANE_KEY_FILE="+nonExistentFile)
+ _, err := cli.config.readTLSOptions(app, vespa.TargetLocal)
+ assert.True(t, os.IsNotExist(err))
}
func TestConfigTargetResolving(t *testing.T) {