Repository: nats-io/nsc
Pull request #308 (2020-10-22 18:49:44)

fixed bogus message
fixed message displayed when saving an activation token to disk.


Patch:
diff --git a/cmd/addimport.go b/cmd/addimport.go
index 21ff93a..36cf73a 100644
--- a/cmd/addimport.go
+++ b/cmd/addimport.go
@@ -71,8 +71,8 @@ type AddImportParams struct {
 
 func (p *AddImportParams) longHelp() string {
 	v := `toolname add import -i
-toolname add import --token-file path --local-subject <sub>
-toolname add import --token https://some.service.com/path --local-subject <sub>
+toolname add import --token <filepath> --local-subject <sub>
+toolname add import --token <some-http-url> --local-subject <sub>
 toolname add import --src-account <account_pubkey> --remote-subject <remote-sub> --local-subject <sub>`
 
 	return strings.Replace(v, "toolname", GetToolName(), -1)
diff --git a/cmd/defaults.go b/cmd/defaults.go
index b8669dc..98da922 100644
--- a/cmd/defaults.go
+++ b/cmd/defaults.go
@@ -25,9 +25,9 @@ import (
 	"strings"
 	"time"
 
-	"github.com/nats-io/jwt"
-
 	"github.com/mitchellh/go-homedir"
+	"github.com/nats-io/jwt"
+	"github.com/nats-io/nats.go"
 	"github.com/nats-io/nsc/cmd/store"
 )
 
@@ -35,6 +35,7 @@ import (
 const NscHomeEnv = "NSC_HOME"
 const NscCwdOnlyEnv = "NSC_CWD_ONLY"
 const NscNoGitIgnoreEnv = "NSC_NO_GIT_IGNORE"
+const NscRootCasNatsEnv = "NATS_CA"
 
 type ToolConfig struct {
 	ContextConfig
@@ -47,6 +48,8 @@ var toolName = strings.ReplaceAll(filepath.Base(os.Args[0]), ".exe", "")
 var config ToolConfig
 var toolHome string
 var homeEnv string
+var rootCAsNats nats.Option // Will be skipped, when nil and passed to a connection
+var rootCAsFile string
 
 func SetToolName(name string) {
 	toolName = name
diff --git a/cmd/env.go b/cmd/env.go
index 39880a4..e7d114a 100644
--- a/cmd/env.go
+++ b/cmd/env.go
@@ -98,6 +98,9 @@ func (p *SetContextParams) PrintEnv(cmd *cobra.Command) {
 	table.AddRow("$"+store.NKeysPathEnv, envSet(store.NKeysPathEnv), AbbrevHomePaths(store.GetKeysDir()))
 	table.AddRow("$"+homeEnv, envSet(homeEnv), AbbrevHomePaths(toolHome))
 	table.AddRow("Config", "", AbbrevHomePaths(conf.configFile()))
+	table.AddRow("$"+NscRootCasNatsEnv, envSet(NscRootCasNatsEnv),
+		"If set, root CAs in the referenced file will be used for nats connections")
+	table.AddRow("", "", "If not set, will default to the system trust store")
 	table.AddSeparator()
 	r := conf.StoreRoot
 	if r == "" {
@@ -107,5 +110,12 @@ func (p *SetContextParams) PrintEnv(cmd *cobra.Command) {
 	table.AddRow("Stores Dir", "", AbbrevHomePaths(r))
 	table.AddRow("Default Operator", "", conf.Operator)
 	table.AddRow("Default Account", "", conf.Account)
+	caFile := rootCAsFile
+	if caFile == "" {
+		caFile = "Default: System Trust Store"
+	} else {
+		caFile = "File: " + caFile
+	}
+	table.AddRow("Root CAs to trust", "", caFile)
 	cmd.Println(table.Render())
 }
diff --git a/cmd/generateactivation.go b/cmd/generateactivation.go
index 21d23b7..c3ddd3d 100644
--- a/cmd/generateactivation.go
+++ b/cmd/generateactivation.go
@@ -270,7 +270,7 @@ func (p *GenerateActivationParams) Run(ctx ActionCtx) (store.Status, error) {
 			return nil, err
 		}
 		if !IsStdOut(p.out) {
-			r.AddOK("wrote account description to %#q", AbbrevHomePaths(p.out))
+			r.AddOK("wrote activation token to %#q", AbbrevHomePaths(p.out))
 		}
 	}
 
diff --git a/cmd/pubtool.go b/cmd/pubtool.go
index c26bbc8..93102f0 100644
--- a/cmd/pubtool.go
+++ b/cmd/pubtool.go
@@ -106,9 +106,8 @@ func (p *PubParams) Validate(ctx ActionCtx) error {
 }
 
 func (p *PubParams) Run(ctx ActionCtx) (store.Status, error) {
-	opts := createDefaultToolOptions("nsc_pub", ctx)
-	opts = append(opts, nats.UserCredentials(p.credsPath))
-	nc, err := nats.Connect(strings.Join(p.natsURLs, ", "), opts...)
+	nc, err := nats.Connect(strings.Join(p.natsURLs, ", "),
+		createDefaultToolOptions("nsc_pub", ctx, nats.UserCredentials(p.credsPath))...)
 	if err != nil {
 		return nil, err
 	}
diff --git a/cmd/pull.go b/cmd/pull.go
index 46c35a7..bb0a516 100644
--- a/cmd/pull.go
+++ b/cmd/pull.go
@@ -246,7 +246,7 @@ func (p *PullParams) Run(ctx ActionCtx) (store.Status, error) {
 			subR.AddError("failed to obtain system user: %v", err)
 			return r, nil
 		}
-		nc, err := nats.Connect(url, opt, nats.Name("nsc-client"))
+		nc, err := nats.Connect(url, createDefaultToolOptions("nsc_pull", ctx, opt)...)
 		if err != nil {
 			subR.AddError("failed to connect to %s: %v", url, err)
 			return r, nil
diff --git a/cmd/push.go b/cmd/push.go
index ca42ab0..3a8fa10 100644
--- a/cmd/push.go
+++ b/cmd/push.go
@@ -376,7 +376,7 @@ func (p *PushCmdParams) Run(ctx ActionCtx) (store.Status, error) {
 			r.AddError("error obtaining system account user: %v", err)
 			return r, nil
 		}
-		nc, err := nats.Connect(p.ASU, opt, nats.Name("nsc-client"))
+		nc, err := nats.Connect(p.ASU, createDefaultToolOptions("nsc_push", ctx, opt)...)
 		if err != nil {
 			r.AddError("failed to connect: %v", err)
 			return r, nil
diff --git a/cmd/replytool.go b/cmd/replytool.go
index 755129c..d4a45f3 100644
--- a/cmd/replytool.go
+++ b/cmd/replytool.go
@@ -111,9 +111,8 @@ func (p *RepParams) Validate(ctx ActionCtx) error {
 }
 
 func (p *RepParams) Run(ctx ActionCtx) (store.Status, error) {
-	opts := createDefaultToolOptions("nscreply", ctx)
-	opts = append(opts, nats.UserCredentials(p.credsPath))
-	nc, err := nats.Connect(strings.Join(p.natsURLs, ","), opts...)
+	nc, err := nats.Connect(strings.Join(p.natsURLs, ","),
+		createDefaultToolOptions("nsc_reply", ctx, nats.UserCredentials(p.credsPath))...)
 	if err != nil {
 		return nil, err
 	}
diff --git a/cmd/reqtool.go b/cmd/reqtool.go
index 7f1b9c3..c44c6d5 100644
--- a/cmd/reqtool.go
+++ b/cmd/reqtool.go
@@ -113,9 +113,8 @@ func (p *ReqParams) Validate(ctx ActionCtx) error {
 }
 
 func (p *ReqParams) Run(ctx ActionCtx) (store.Status, error) {
-	opts := createDefaultToolOptions("nsc_req", ctx)
-	opts = append(opts, nats.UserCredentials(p.credsPath))
-	nc, err := nats.Connect(strings.Join(p.natsURLs, ", "), opts...)
+	nc, err := nats.Connect(strings.Join(p.natsURLs, ", "),
+		createDefaultToolOptions("nsc_req", ctx, nats.UserCredentials(p.credsPath))...)
 	if err != nil {
 		return nil, err
 	}
diff --git a/cmd/root.go b/cmd/root.go
index ccc25e7..aa11d13 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -21,9 +21,11 @@ import (
 	"io"
 	"os"
 	"path/filepath"
+	"strings"
 
 	"github.com/mitchellh/go-homedir"
 	cli "github.com/nats-io/cliprompts/v2"
+	"github.com/nats-io/nats.go"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
 	"github.com/spf13/cobra"
@@ -155,6 +157,10 @@ func SetEnvOptions() {
 	if _, ok := os.LookupEnv(NscCwdOnlyEnv); ok {
 		NscCwdOnly = true
 	}
+	if f, ok := os.LookupEnv(NscRootCasNatsEnv); ok {
+		rootCAsFile = strings.TrimSpace(f)
+		rootCAsNats = nats.RootCAs(rootCAsFile)
+	}
 }
 
 func init() {
diff --git a/cmd/rtttool.go b/cmd/rtttool.go
index acc3aba..ffa0147 100644
--- a/cmd/rtttool.go
+++ b/cmd/rtttool.go
@@ -103,9 +103,8 @@ func (p *RttParams) Validate(ctx ActionCtx) error {
 }
 
 func (p *RttParams) Run(ctx ActionCtx) (store.Status, error) {
-	opts := createDefaultToolOptions("nsc_rtt", ctx)
-	opts = append(opts, nats.UserCredentials(p.credsPath))
-	nc, err := nats.Connect(strings.Join(p.natsURLs, ", "), opts...)
+	nc, err := nats.Connect(strings.Join(p.natsURLs, ", "),
+		createDefaultToolOptions("nsc_rtt", ctx, nats.UserCredentials(p.credsPath))...)
 	if err != nil {
 		return nil, err
 	}
diff --git a/cmd/subtool.go b/cmd/subtool.go
index d4445f4..4b47a99 100644
--- a/cmd/subtool.go
+++ b/cmd/subtool.go
@@ -115,9 +115,8 @@ func (p *SubParams) Validate(ctx ActionCtx) error {
 }
 
 func (p *SubParams) Run(ctx ActionCtx) (store.Status, error) {
-	opts := createDefaultToolOptions("nscsub", ctx)
-	opts = append(opts, nats.UserCredentials(p.credsPath))
-	nc, err := nats.Connect(strings.Join(p.natsURLs, ", "), opts...)
+	nc, err := nats.Connect(strings.Join(p.natsURLs, ", "),
+		createDefaultToolOptions("nsc_sub", ctx, nats.UserCredentials(p.credsPath))...)
 	if err != nil {
 		return nil, err
 	}
diff --git a/cmd/tool.go b/cmd/tool.go
index 6d69951..9439a7d 100644
--- a/cmd/tool.go
+++ b/cmd/tool.go
@@ -44,13 +44,14 @@ func init() {
 	GetRootCmd().AddCommand(toolCmd)
 }
 
-func createDefaultToolOptions(name string, ctx ActionCtx) []nats.Option {
+func createDefaultToolOptions(name string, ctx ActionCtx, o ...nats.Option) []nats.Option {
 	connectTimeout := 5 * time.Second
 	totalWait := 10 * time.Minute
 	reconnectDelay := 2 * time.Second
 
 	opts := []nats.Option{nats.Name(name)}
 	opts = append(opts, nats.Timeout(connectTimeout))
+	opts = append(opts, rootCAsNats)
 	opts = append(opts, nats.ReconnectWait(reconnectDelay))
 	opts = append(opts, nats.MaxReconnects(int(totalWait/reconnectDelay)))
 	opts = append(opts, nats.DisconnectErrHandler(func(nc *nats.Conn, err error) {
@@ -71,6 +72,7 @@ func createDefaultToolOptions(name string, ctx ActionCtx) []nats.Option {
 		}
 		ctx.CurrentCmd().Printf("Exiting, no servers available, or connection closed")
 	}))
+	opts = append(opts, o...)
 	return opts
 }
 


Test patch:
diff --git a/cmd/tools_test.go b/cmd/tools_test.go
index 746e2c0..ba86a25 100644
--- a/cmd/tools_test.go
+++ b/cmd/tools_test.go
@@ -112,7 +112,7 @@ func TestSub(t *testing.T) {
 	}()
 
 	// wait for client
-	ts.WaitForClient(t, "nscsub", 1, 60*time.Second)
+	ts.WaitForClient(t, "nsc_sub", 1, 60*time.Second)
 
 	// create a conn to the server
 	creds := ts.KeyStore.CalcUserCredsPath("A", "U")
@@ -213,7 +213,7 @@ func TestReply(t *testing.T) {
 	}()
 
 	// wait for client
-	ts.WaitForClient(t, "nscreply", 1, 60*time.Second)
+	ts.WaitForClient(t, "nsc_reply", 1, 60*time.Second)
 
 	// create a conn to the server
 	creds := ts.KeyStore.CalcUserCredsPath("A", "U")