Repository: nats-io/nsc
Pull request #48 (2018-12-10 02:20:16)

Short codes


Patch:
diff --git a/cmd/common.go b/cmd/common.go
index 5d6603f..8acefff 100644
--- a/cmd/common.go
+++ b/cmd/common.go
@@ -225,7 +225,7 @@ func ParseNumber(s string) (int64, error) {
 		}
 		return v, nil
 	}
-	re = regexp.MustCompile(`(-?\d+)([B|K|M|G])`)
+	re = regexp.MustCompile(`(-?\d+)([BKMG])`)
 	m = re.FindStringSubmatch(s)
 	if m != nil {
 		v, err := strconv.ParseInt(m[1], 10, 64)
@@ -255,7 +255,8 @@ func UnixToDate(d int64) string {
 	if d == 0 {
 		return ""
 	}
-	return time.Unix(d, 0).UTC().String()
+
+	return strings.Replace(time.Unix(d, 0).UTC().String(), " +0000", "", -1)
 }
 
 func HumanizedDate(d int64) string {
@@ -272,6 +273,14 @@ func HumanizedDate(d int64) string {
 	}
 }
 
+func RenderDate(d int64) string {
+	if d == 0 {
+		return ""
+	}
+
+	return fmt.Sprintf("%s (%s)", UnixToDate(d), HumanizedDate(d))
+}
+
 func NKeyValidator(kind nkeys.PrefixByte) cli.Validator {
 	return func(v string) error {
 		nk, err := store.ResolveKey(v)
@@ -364,3 +373,15 @@ func MaxArgs(max int) cobra.PositionalArgs {
 	}
 	return cobra.MaximumNArgs(max)
 }
+
+// ShortKey returns the first 12 characters of a public key (or the key if it is < 12 long)
+func ShortCodes(s string) string {
+	if WideFlag {
+		return s
+	}
+	if s != "" && len(s) > 12 {
+		s = s[0:12]
+	}
+
+	return s
+}
diff --git a/cmd/describer.go b/cmd/describer.go
index f537fdf..dc33e8e 100644
--- a/cmd/describer.go
+++ b/cmd/describer.go
@@ -48,6 +48,7 @@ func (a *AccountDescriber) Describe() string {
 	table.AddRow("Name", a.Name)
 	AddStandardClaimInfo(table, a.ClaimsData)
 
+	table.AddSeparator()
 	lim := a.Limits
 	if lim.Conn > -1 {
 		table.AddRow("Max Connections", fmt.Sprintf("%d", lim.Conn))
@@ -91,14 +92,20 @@ func (a *AccountDescriber) Describe() string {
 	}
 	table.AddRow("Exports Allows Wildcards", we)
 
+	table.AddSeparator()
+
 	if len(a.Imports) == 0 {
-		table.AddRow("Imports", "No services or streams imported")
+		table.AddRow("Imports", "None")
 	}
 
 	if len(a.Exports) == 0 {
-		table.AddRow("Exports", "No services or streams exported")
+		table.AddRow("Exports", "None")
+	}
+
+	if len(a.Tags) > 0 {
+		table.AddSeparator()
+		AddListValues(table, "Tags", a.Tags)
 	}
-	AddListValues(table, "Tags", a.Tags)
 
 	buf.WriteString(table.Render())
 
@@ -154,7 +161,7 @@ func NewImportsDescriber(imports jwt.Imports) *ImportsDescriber {
 func (i *ImportsDescriber) Describe() string {
 	table := tablewriter.CreateTable()
 	table.AddTitle("Imports")
-	table.AddHeaders("Type", "Subject", "To", "Expires")
+	table.AddHeaders("Type", "Subject", "To", "Expires", "From Account")
 
 	for _, v := range i.Imports {
 		NewImportDescriber(*v).Brief(table)
@@ -173,7 +180,7 @@ func NewImportDescriber(im jwt.Import) *ImportDescriber {
 
 func (i *ImportDescriber) Brief(table *tablewriter.Table) {
 	if i.Token == "" {
-		table.AddRow(strings.Title(i.Type.String()), string(i.Subject), string(i.To), "")
+		table.AddRow(strings.Title(i.Type.String()), string(i.Subject), string(i.To), "", ShortCodes(i.Account))
 		return
 	}
 	expiration := ""
@@ -181,9 +188,9 @@ func (i *ImportDescriber) Brief(table *tablewriter.Table) {
 	if err != nil {
 		expiration = fmt.Sprintf("error decoding: %v", err.Error())
 	} else {
-		expiration = fmt.Sprintf("%s (%s)", UnixToDate(ac.Expires), HumanizedDate(ac.Expires))
+		expiration = RenderDate(ac.Expires)
 	}
-	table.AddRow(strings.Title(i.Type.String()), string(i.Subject), string(i.To), expiration)
+	table.AddRow(strings.Title(i.Type.String()), string(i.Subject), string(i.To), expiration, ShortCodes(i.Account))
 }
 
 func (i *ImportDescriber) IsRemoteImport() bool {
@@ -208,15 +215,10 @@ func (i *ImportDescriber) LoadActivation() (*jwt.ActivationClaims, error) {
 }
 
 func AddStandardClaimInfo(table *tablewriter.Table, cd jwt.ClaimsData) {
-	table.AddRow("Account ID", cd.Subject)
-	table.AddRow("Issuer ID", cd.Issuer)
-	table.AddRow("Issued", fmt.Sprintf("%s (%s)", UnixToDate(cd.IssuedAt), HumanizedDate(cd.IssuedAt)))
-
-	if cd.Expires > 0 {
-		table.AddRow("Expires", fmt.Sprintf("%s (%s)", UnixToDate(cd.Expires), HumanizedDate(cd.Expires)))
-	} else {
-		table.AddRow("Expires", "No expiration")
-	}
+	table.AddRow("Account ID", ShortCodes(cd.Subject))
+	table.AddRow("Issuer ID", ShortCodes(cd.Issuer))
+	table.AddRow("Issued", RenderDate(cd.IssuedAt))
+	table.AddRow("Expires", RenderDate(cd.Expires))
 }
 
 type ActivationDescriber struct {
@@ -233,9 +235,10 @@ func (c *ActivationDescriber) Describe() string {
 	table.AddTitle("Activation")
 	table.AddRow("Import Type", strings.Title(c.ImportType.String()))
 	table.AddRow("Import Subject", string(c.ImportSubject))
-
 	AddStandardClaimInfo(table, c.ActivationClaims.ClaimsData)
 
+	table.AddSeparator()
+
 	AddLimits(table, c.Limits)
 
 	return table.Render()
@@ -298,22 +301,27 @@ func (u *UserDescriber) Describe() string {
 	table.UTF8Box()
 	table.AddTitle("User")
 	table.AddRow("Name", u.Name)
-	table.AddRow("User ID", u.Subject)
-	table.AddRow("Issuer ID", u.Issuer)
-	AddListValues(table, "Pub Allow", u.Pub.Allow)
-	AddListValues(table, "Pub Deny", u.Pub.Deny)
-	AddListValues(table, "Sub Allow", u.Sub.Allow)
-	AddListValues(table, "Sub Deny", u.Sub.Deny)
+	table.AddRow("User ID", ShortCodes(u.Subject))
+	table.AddRow("Issuer ID", ShortCodes(u.Issuer))
+	table.AddRow("Issued", RenderDate(u.IssuedAt))
+	table.AddRow("Expires", RenderDate(u.Expires))
+
+	if len(u.Pub.Allow) > 0 || len(u.Pub.Deny) > 0 ||
+		len(u.Sub.Allow) > 0 || len(u.Sub.Deny) > 0 {
+		table.AddSeparator()
+		AddListValues(table, "Pub Allow", u.Pub.Allow)
+		AddListValues(table, "Pub Deny", u.Pub.Deny)
+		AddListValues(table, "Sub Allow", u.Sub.Allow)
+		AddListValues(table, "Sub Deny", u.Sub.Deny)
+	}
 
+	table.AddSeparator()
 	AddLimits(table, u.Limits)
 
-	table.AddRow("Issued", fmt.Sprintf("%s (%s)", UnixToDate(u.IssuedAt), HumanizedDate(u.IssuedAt)))
-	if u.Expires > 0 {
-		table.AddRow("Expires", fmt.Sprintf("%s (%s)", UnixToDate(u.Expires), HumanizedDate(u.Expires)))
-	} else {
-		table.AddRow("Expires", "No expiration")
+	if len(u.Tags) > 0 {
+		table.AddSeparator()
+		AddListValues(table, "Tags", u.Tags)
 	}
-	AddListValues(table, "Tags", u.Tags)
 
 	return table.Render()
 }
@@ -331,26 +339,26 @@ func (c *ClusterDescriber) Describe() string {
 	table.UTF8Box()
 	table.AddTitle("Cluster")
 	table.AddRow("Name", c.Name)
-	table.AddRow("Cluster ID", c.Subject)
-	table.AddRow("Issuer ID", c.Issuer)
+	table.AddRow("Cluster ID", ShortCodes(c.Subject))
+	table.AddRow("Issuer ID", ShortCodes(c.Issuer))
+	table.AddRow("Issued", RenderDate(c.IssuedAt))
+	table.AddRow("Expires", RenderDate(c.Expires))
+
+	table.AddSeparator()
 
 	AddListValues(table, "Trusted Operators", c.Trust)
 	if c.OperatorURL != "" {
 		table.AddRow("Operator Srv", c.OperatorURL)
 	}
 
+	table.AddSeparator()
+
 	AddListValues(table, "Trusted Accounts", c.Accounts)
 	if c.AccountURL != "" {
 		table.AddRow("Account Srv", c.AccountURL)
 	}
 
-	table.AddRow("Issued", fmt.Sprintf("%s (%s)", UnixToDate(c.IssuedAt), HumanizedDate(c.IssuedAt)))
-	if c.Expires > 0 {
-		table.AddRow("Expires", fmt.Sprintf("%s (%s)", UnixToDate(c.Expires), HumanizedDate(c.Expires)))
-	} else {
-		table.AddRow("Expires", "No expiration")
-	}
-
+	table.AddSeparator()
 	AddListValues(table, "Tags", c.Tags)
 
 	return table.Render()
@@ -369,15 +377,13 @@ func (s *ServerDescriber) Describe() string {
 	table.UTF8Box()
 	table.AddTitle("Server")
 	table.AddRow("Name", s.Name)
-	table.AddRow("Server ID", s.Subject)
-	table.AddRow("Issuer ID", s.Issuer)
+	table.AddRow("Server ID", ShortCodes(s.Subject))
+	table.AddRow("Issuer ID", ShortCodes(s.Issuer))
+	table.AddRow("Issued", RenderDate(s.IssuedAt))
+	table.AddRow("Expires", RenderDate(s.Expires))
+
+	table.AddSeparator()
 
-	table.AddRow("Issued", fmt.Sprintf("%s (%s)", UnixToDate(s.IssuedAt), HumanizedDate(s.IssuedAt)))
-	if s.Expires > 0 {
-		table.AddRow("Expires", fmt.Sprintf("%s (%s)", UnixToDate(s.Expires), HumanizedDate(s.Expires)))
-	} else {
-		table.AddRow("Expires", "No expiration")
-	}
 	AddListValues(table, "Tags", s.Tags)
 
 	return table.Render()
@@ -396,23 +402,26 @@ func (o *OperatorDescriber) Describe() string {
 	table.UTF8Box()
 	table.AddTitle("Operator")
 	table.AddRow("Name", o.Name)
-	table.AddRow("Operator ID", o.Subject)
+	table.AddRow("Operator ID", ShortCodes(o.Subject))
+	table.AddRow("Issued", RenderDate(o.IssuedAt))
+	table.AddRow("Expires", RenderDate(o.Expires))
 
 	if len(o.Identities) > 0 {
+		table.AddSeparator()
 		for _, v := range o.Identities {
 			table.AddRow(fmt.Sprintf("ID %s", v.ID), v.Proof)
 		}
 	}
 
-	AddListValues(table, "Signing Keys", o.SigningKeys)
+	if len(o.SigningKeys) > 0 {
+		table.AddSeparator()
+		AddListValues(table, "Signing Keys", o.SigningKeys)
+	}
 
-	table.AddRow("Issued", fmt.Sprintf("%s (%s)", UnixToDate(o.IssuedAt), HumanizedDate(o.IssuedAt)))
-	if o.Expires > 0 {
-		table.AddRow("Expires", fmt.Sprintf("%s (%s)", UnixToDate(o.Expires), HumanizedDate(o.Expires)))
-	} else {
-		table.AddRow("Expires", "No expiration")
+	if len(o.Tags) > 0 {
+		table.AddSeparator()
+		AddListValues(table, "Tags", o.Tags)
 	}
-	AddListValues(table, "Tags", o.Tags)
 
 	return table.Render()
 }
diff --git a/cmd/list.go b/cmd/list.go
index e62df02..dbd9dfe 100644
--- a/cmd/list.go
+++ b/cmd/list.go
@@ -289,7 +289,11 @@ func listEntities(title string, infos []*listEntry, current string) string {
 	if len(infos) == 0 {
 		table.AddRow("No entries defined")
 	} else {
-		table.AddHeaders("Name", "Public Key")
+		if !WideFlag {
+			table.AddHeaders("Name", "Public Key (-W for long)")
+		} else {
+			table.AddHeaders("Name", "Public Key")
+		}
 		for _, v := range infos {
 			n := v.name
 			var p string
@@ -302,7 +306,7 @@ func listEntities(title string, infos []*listEntry, current string) string {
 					if n != tn {
 						n = fmt.Sprintf("%s (%s)", n, c.Name)
 					}
-					p = c.Subject
+					p = ShortCodes(c.Subject)
 				}
 			}
 			if n == current {
diff --git a/cmd/root.go b/cmd/root.go
index 090c594..2a98ad3 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -34,6 +34,7 @@ const TestEnv = "NSC_TEST"
 
 var KeyPathFlag string
 var InteractiveFlag bool
+var WideFlag bool
 var quietMode bool
 
 var cfgFile string
@@ -148,6 +149,7 @@ func init() {
 func HoistRootFlags(cmd *cobra.Command) *cobra.Command {
 	cmd.PersistentFlags().StringVarP(&KeyPathFlag, "private-key", "K", "", "private key")
 	cmd.PersistentFlags().BoolVarP(&InteractiveFlag, "interactive", "i", false, "ask questions for various settings")
+	cmd.PersistentFlags().BoolVarP(&WideFlag, "long-ids", "W", false, "display long ids")
 
 	return cmd
 }


Test patch:
diff --git a/cmd/util_test.go b/cmd/util_test.go
index 0add517..d34ccb9 100644
--- a/cmd/util_test.go
+++ b/cmd/util_test.go
@@ -43,6 +43,7 @@ type TestStore struct {
 func NewTestStoreWithOperator(t *testing.T, operatorName string, operator nkeys.KeyPair) *TestStore {
 	ResetConfigForTests()
 	var ts TestStore
+	WideFlag = true
 
 	// ngsStore is a global - so first test to get it initializes it
 	ngsStore = nil