open-consul/command/acl/token/formatter.go
R.B. Boyer 265d2ea9e1
acl: add DisplayName field to auth methods (#7769)
Also add a few missing acl fields in the api.
2020-05-04 15:18:25 -05:00

188 lines
5.8 KiB
Go

package token
import (
"bytes"
"encoding/json"
"fmt"
"strings"
"github.com/hashicorp/consul/api"
)
const (
PrettyFormat string = "pretty"
JSONFormat string = "json"
)
// Formatter defines methods provided by token command output formatter
type Formatter interface {
FormatToken(token *api.ACLToken) (string, error)
FormatTokenList(tokens []*api.ACLTokenListEntry) (string, error)
}
// GetSupportedFormats returns supported formats
func GetSupportedFormats() []string {
return []string{PrettyFormat, JSONFormat}
}
// NewFormatter returns Formatter implementation
func NewFormatter(format string, showMeta bool) (formatter Formatter, err error) {
switch format {
case PrettyFormat:
formatter = newPrettyFormatter(showMeta)
case JSONFormat:
formatter = newJSONFormatter(showMeta)
default:
err = fmt.Errorf("Unknown format: %s", format)
}
return formatter, err
}
func newPrettyFormatter(showMeta bool) Formatter {
return &prettyFormatter{showMeta}
}
type prettyFormatter struct {
showMeta bool
}
func (f *prettyFormatter) FormatToken(token *api.ACLToken) (string, error) {
var buffer bytes.Buffer
buffer.WriteString(fmt.Sprintf("AccessorID: %s\n", token.AccessorID))
buffer.WriteString(fmt.Sprintf("SecretID: %s\n", token.SecretID))
if token.Namespace != "" {
buffer.WriteString(fmt.Sprintf("Namespace: %s\n", token.Namespace))
}
buffer.WriteString(fmt.Sprintf("Description: %s\n", token.Description))
buffer.WriteString(fmt.Sprintf("Local: %t\n", token.Local))
if token.AuthMethod != "" {
buffer.WriteString(fmt.Sprintf("Auth Method: %s\n", token.AuthMethod))
}
buffer.WriteString(fmt.Sprintf("Create Time: %v\n", token.CreateTime))
if token.ExpirationTime != nil && !token.ExpirationTime.IsZero() {
buffer.WriteString(fmt.Sprintf("Expiration Time: %v\n", *token.ExpirationTime))
}
if f.showMeta {
buffer.WriteString(fmt.Sprintf("Hash: %x\n", token.Hash))
buffer.WriteString(fmt.Sprintf("Create Index: %d\n", token.CreateIndex))
buffer.WriteString(fmt.Sprintf("Modify Index: %d\n", token.ModifyIndex))
}
if len(token.Policies) > 0 {
buffer.WriteString(fmt.Sprintln("Policies:"))
for _, policy := range token.Policies {
buffer.WriteString(fmt.Sprintf(" %s - %s\n", policy.ID, policy.Name))
}
}
if len(token.Roles) > 0 {
buffer.WriteString(fmt.Sprintln("Roles:"))
for _, role := range token.Roles {
buffer.WriteString(fmt.Sprintf(" %s - %s\n", role.ID, role.Name))
}
}
if len(token.ServiceIdentities) > 0 {
buffer.WriteString(fmt.Sprintln("Service Identities:"))
for _, svcid := range token.ServiceIdentities {
if len(svcid.Datacenters) > 0 {
buffer.WriteString(fmt.Sprintf(" %s (Datacenters: %s)\n", svcid.ServiceName, strings.Join(svcid.Datacenters, ", ")))
} else {
buffer.WriteString(fmt.Sprintf(" %s (Datacenters: all)\n", svcid.ServiceName))
}
}
}
if token.Rules != "" {
buffer.WriteString(fmt.Sprintln("Rules:"))
buffer.WriteString(fmt.Sprintln(token.Rules))
}
return buffer.String(), nil
}
func (f *prettyFormatter) FormatTokenList(tokens []*api.ACLTokenListEntry) (string, error) {
var buffer bytes.Buffer
first := true
for _, token := range tokens {
if first {
first = false
} else {
buffer.WriteString("\n")
}
buffer.WriteString(f.formatTokenListEntry(token))
}
return buffer.String(), nil
}
func (f *prettyFormatter) formatTokenListEntry(token *api.ACLTokenListEntry) string {
var buffer bytes.Buffer
buffer.WriteString(fmt.Sprintf("AccessorID: %s\n", token.AccessorID))
if token.Namespace != "" {
buffer.WriteString(fmt.Sprintf("Namespace: %s\n", token.Namespace))
}
buffer.WriteString(fmt.Sprintf("Description: %s\n", token.Description))
buffer.WriteString(fmt.Sprintf("Local: %t\n", token.Local))
if token.AuthMethod != "" {
buffer.WriteString(fmt.Sprintf("Auth Method: %s\n", token.AuthMethod))
}
buffer.WriteString(fmt.Sprintf("Create Time: %v\n", token.CreateTime))
if token.ExpirationTime != nil && !token.ExpirationTime.IsZero() {
buffer.WriteString(fmt.Sprintf("Expiration Time: %v\n", *token.ExpirationTime))
}
buffer.WriteString(fmt.Sprintf("Legacy: %t\n", token.Legacy))
if f.showMeta {
buffer.WriteString(fmt.Sprintf("Hash: %x\n", token.Hash))
buffer.WriteString(fmt.Sprintf("Create Index: %d\n", token.CreateIndex))
buffer.WriteString(fmt.Sprintf("Modify Index: %d\n", token.ModifyIndex))
}
if len(token.Policies) > 0 {
buffer.WriteString(fmt.Sprintln("Policies:"))
for _, policy := range token.Policies {
buffer.WriteString(fmt.Sprintf(" %s - %s\n", policy.ID, policy.Name))
}
}
if len(token.Roles) > 0 {
buffer.WriteString(fmt.Sprintln("Roles:"))
for _, role := range token.Roles {
buffer.WriteString(fmt.Sprintf(" %s - %s\n", role.ID, role.Name))
}
}
if len(token.ServiceIdentities) > 0 {
buffer.WriteString(fmt.Sprintln("Service Identities:"))
for _, svcid := range token.ServiceIdentities {
if len(svcid.Datacenters) > 0 {
buffer.WriteString(fmt.Sprintf(" %s (Datacenters: %s)\n", svcid.ServiceName, strings.Join(svcid.Datacenters, ", ")))
} else {
buffer.WriteString(fmt.Sprintf(" %s (Datacenters: all)\n", svcid.ServiceName))
}
}
}
return buffer.String()
}
func newJSONFormatter(showMeta bool) Formatter {
return &jsonFormatter{showMeta}
}
type jsonFormatter struct {
showMeta bool
}
func (f *jsonFormatter) FormatTokenList(tokens []*api.ACLTokenListEntry) (string, error) {
b, err := json.MarshalIndent(tokens, "", " ")
if err != nil {
return "", fmt.Errorf("Failed to marshal tokens: %v", err)
}
return string(b), nil
}
func (f *jsonFormatter) FormatToken(token *api.ACLToken) (string, error) {
b, err := json.MarshalIndent(token, "", " ")
if err != nil {
return "", fmt.Errorf("Failed to marshal token: %v", err)
}
return string(b), nil
}