summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2021-08-25 14:41:24 +0200
committerMartin Polden <mpolden@mpolden.no>2021-08-25 18:56:03 +0200
commit240fb94f82b8a59e70135deee6bc870e8ced2673 (patch)
tree1fc1fc46213856ff2565e4383d2dbb303d26f174 /client
parentdfa5970405e3f9182bed4fc9f4422eb81aae13d2 (diff)
Implement vespa cert
Diffstat (limited to 'client')
-rw-r--r--client/go/cmd/cert.go70
-rw-r--r--client/go/cmd/config.go6
-rw-r--r--client/go/util/print.go8
-rw-r--r--client/go/vespa/crypto_test.go2
4 files changed, 83 insertions, 3 deletions
diff --git a/client/go/cmd/cert.go b/client/go/cmd/cert.go
new file mode 100644
index 00000000000..8b75ad2a509
--- /dev/null
+++ b/client/go/cmd/cert.go
@@ -0,0 +1,70 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+// vespa cert command
+// Author: mpolden
+package cmd
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "github.com/spf13/cobra"
+ "github.com/vespa-engine/vespa/util"
+ "github.com/vespa-engine/vespa/vespa"
+)
+
+var overwriteCertificate bool
+
+func init() {
+ certCmd.Flags().BoolVarP(&overwriteCertificate, "force", "f", false, "Force overwrite of existing certificate and private key")
+ rootCmd.AddCommand(certCmd)
+}
+
+var certCmd = &cobra.Command{
+ Use: "cert",
+ Short: "Creates a new private key and self-signed certificate",
+ Long: `Applications in Vespa Cloud are required to secure their data plane with mutual TLS. ` +
+ `This command creates a self-signed certificate suitable for development purposes. ` +
+ `See https://cloud.vespa.ai/en/security-model for more information on the Vespa Cloud security model.`,
+ Run: func(cmd *cobra.Command, args []string) {
+ var path string
+ if len(args) > 0 {
+ path = args[0]
+ } else {
+ var err error
+ path, err = os.Getwd()
+ util.FatalIfErr(err)
+ }
+
+ pkg, err := vespa.FindApplicationPackage(path)
+ util.FatalIfErr(err)
+ if pkg.HasCertificate() {
+ util.Print("Certificate already exists")
+ return
+ }
+
+ // TODO: Consider writing key pair inside ~/.vespa/<app-name>/ instead so that vespa document commands can easily
+ // locate key pair
+ securityDir := filepath.Join(pkg.Path, "security")
+ privateKeyFile := filepath.Join(path, "data-plane-private-key.pem")
+ certificateFile := filepath.Join(path, "data-plane-public-cert.pem")
+ pkgCertificateFile := filepath.Join(securityDir, "clients.pem")
+
+ keyPair, err := vespa.CreateKeyPair()
+ util.FatalIfErr(err)
+
+ err = os.MkdirAll(securityDir, 0755)
+ util.FatalIfErr(err)
+ err = keyPair.WriteCertificateFile(pkgCertificateFile, overwriteCertificate)
+ util.FatalIfErr(err)
+ err = keyPair.WriteCertificateFile(certificateFile, overwriteCertificate)
+ util.FatalIfErr(err)
+ err = keyPair.WritePrivateKeyFile(privateKeyFile, overwriteCertificate)
+ util.FatalIfErr(err)
+
+ // TODO: Just use log package, which has Printf
+ util.Print(fmt.Sprintf("Certificate written to %s", pkgCertificateFile))
+ util.Print(fmt.Sprintf("Certificate written to %s", certificateFile))
+ util.Print(fmt.Sprintf("Private key written to %s", privateKeyFile))
+ },
+}
diff --git a/client/go/cmd/config.go b/client/go/cmd/config.go
index 6d25f33d07c..9435a97d999 100644
--- a/client/go/cmd/config.go
+++ b/client/go/cmd/config.go
@@ -5,11 +5,12 @@
package cmd
import (
+ "os"
+ "path/filepath"
+
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/vespa-engine/vespa/util"
- "os"
- "path/filepath"
)
func init() {
@@ -25,6 +26,7 @@ var configCmd = &cobra.Command{
}
func readConfig() {
+ // TODO: Make ~/.vespa a directory so that we can put other files there as well
home, err := os.UserHomeDir()
configName := ".vespa"
configType := "yaml"
diff --git a/client/go/util/print.go b/client/go/util/print.go
index 6f6e40be07f..ed3a3a1d18a 100644
--- a/client/go/util/print.go
+++ b/client/go/util/print.go
@@ -29,6 +29,14 @@ func Error(messages ...string) {
print("\033[31m", messages)
}
+// FatalIfError prints error and exists if given err is non-nill.
+func FatalIfErr(err error) {
+ if err != nil {
+ Error(err.Error())
+ os.Exit(1)
+ }
+}
+
// Prints in a color appropriate for success messages
func Success(messages ...string) {
print("\033[32m", messages)
diff --git a/client/go/vespa/crypto_test.go b/client/go/vespa/crypto_test.go
index 5ac8464e4b0..6a6d1d6a10a 100644
--- a/client/go/vespa/crypto_test.go
+++ b/client/go/vespa/crypto_test.go
@@ -1,8 +1,8 @@
package vespa
import (
- "testing"
"github.com/stretchr/testify/assert"
+ "testing"
)
func TestCreateKeyPair(t *testing.T) {