mirror of https://github.com/hashicorp/consul
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
6.4 KiB
201 lines
6.4 KiB
// Copyright (c) HashiCorp, Inc. |
|
// SPDX-License-Identifier: BUSL-1.1 |
|
|
|
package role |
|
|
|
import ( |
|
"bytes" |
|
"encoding/json" |
|
"fmt" |
|
"strings" |
|
|
|
"github.com/hashicorp/consul/api" |
|
) |
|
|
|
const ( |
|
PrettyFormat string = "pretty" |
|
JSONFormat string = "json" |
|
) |
|
|
|
// Formatter defines methods provided by role command output formatter |
|
type Formatter interface { |
|
FormatRole(role *api.ACLRole) (string, error) |
|
FormatRoleList(roles []*api.ACLRole) (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) FormatRole(role *api.ACLRole) (string, error) { |
|
var buffer bytes.Buffer |
|
|
|
buffer.WriteString(fmt.Sprintf("ID: %s\n", role.ID)) |
|
buffer.WriteString(fmt.Sprintf("Name: %s\n", role.Name)) |
|
if role.Partition != "" { |
|
buffer.WriteString(fmt.Sprintf("Partition: %s\n", role.Partition)) |
|
} |
|
if role.Namespace != "" { |
|
buffer.WriteString(fmt.Sprintf("Namespace: %s\n", role.Namespace)) |
|
} |
|
buffer.WriteString(fmt.Sprintf("Description: %s\n", role.Description)) |
|
if f.showMeta { |
|
buffer.WriteString(fmt.Sprintf("Hash: %x\n", role.Hash)) |
|
buffer.WriteString(fmt.Sprintf("Create Index: %d\n", role.CreateIndex)) |
|
buffer.WriteString(fmt.Sprintf("Modify Index: %d\n", role.ModifyIndex)) |
|
} |
|
if len(role.Policies) > 0 { |
|
buffer.WriteString(fmt.Sprintln("Policies:")) |
|
for _, policy := range role.Policies { |
|
buffer.WriteString(fmt.Sprintf(" %s - %s\n", policy.ID, policy.Name)) |
|
} |
|
} |
|
if len(role.ServiceIdentities) > 0 { |
|
buffer.WriteString(fmt.Sprintln("Service Identities:")) |
|
for _, svcid := range role.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 len(role.NodeIdentities) > 0 { |
|
buffer.WriteString(fmt.Sprintln("Node Identities:")) |
|
for _, nodeid := range role.NodeIdentities { |
|
buffer.WriteString(fmt.Sprintf(" %s (Datacenter: %s)\n", nodeid.NodeName, nodeid.Datacenter)) |
|
} |
|
} |
|
if len(role.TemplatedPolicies) > 0 { |
|
buffer.WriteString(fmt.Sprintln("Templated Policies:")) |
|
for _, templatedPolicy := range role.TemplatedPolicies { |
|
buffer.WriteString(fmt.Sprintf(" %s\n", templatedPolicy.TemplateName)) |
|
if templatedPolicy.TemplateVariables != nil && templatedPolicy.TemplateVariables.Name != "" { |
|
buffer.WriteString(fmt.Sprintf(" Name: %s\n", templatedPolicy.TemplateVariables.Name)) |
|
} |
|
if len(templatedPolicy.Datacenters) > 0 { |
|
buffer.WriteString(fmt.Sprintf(" Datacenters: %s\n", strings.Join(templatedPolicy.Datacenters, ", "))) |
|
} else { |
|
buffer.WriteString(" Datacenters: all\n") |
|
} |
|
} |
|
} |
|
|
|
return buffer.String(), nil |
|
} |
|
|
|
func (f *prettyFormatter) FormatRoleList(roles []*api.ACLRole) (string, error) { |
|
var buffer bytes.Buffer |
|
|
|
for _, role := range roles { |
|
buffer.WriteString(f.formatRoleListEntry(role)) |
|
} |
|
|
|
return buffer.String(), nil |
|
} |
|
|
|
func (f *prettyFormatter) formatRoleListEntry(role *api.ACLRole) string { |
|
var buffer bytes.Buffer |
|
|
|
buffer.WriteString(fmt.Sprintf("%s:\n", role.Name)) |
|
buffer.WriteString(fmt.Sprintf(" ID: %s\n", role.ID)) |
|
if role.Partition != "" { |
|
buffer.WriteString(fmt.Sprintf(" Partition: %s\n", role.Partition)) |
|
} |
|
if role.Namespace != "" { |
|
buffer.WriteString(fmt.Sprintf(" Namespace: %s\n", role.Namespace)) |
|
} |
|
buffer.WriteString(fmt.Sprintf(" Description: %s\n", role.Description)) |
|
if f.showMeta { |
|
buffer.WriteString(fmt.Sprintf(" Hash: %x\n", role.Hash)) |
|
buffer.WriteString(fmt.Sprintf(" Create Index: %d\n", role.CreateIndex)) |
|
buffer.WriteString(fmt.Sprintf(" Modify Index: %d\n", role.ModifyIndex)) |
|
} |
|
if len(role.Policies) > 0 { |
|
buffer.WriteString(fmt.Sprintln(" Policies:")) |
|
for _, policy := range role.Policies { |
|
buffer.WriteString(fmt.Sprintf(" %s - %s\n", policy.ID, policy.Name)) |
|
} |
|
} |
|
if len(role.ServiceIdentities) > 0 { |
|
buffer.WriteString(fmt.Sprintln(" Service Identities:")) |
|
for _, svcid := range role.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 len(role.NodeIdentities) > 0 { |
|
buffer.WriteString(fmt.Sprintln(" Node Identities:")) |
|
for _, nodeid := range role.NodeIdentities { |
|
buffer.WriteString(fmt.Sprintf(" %s (Datacenter: %s)\n", nodeid.NodeName, nodeid.Datacenter)) |
|
} |
|
} |
|
|
|
if len(role.TemplatedPolicies) > 0 { |
|
buffer.WriteString(fmt.Sprintln(" Templated Policies:")) |
|
for _, templatedPolicy := range role.TemplatedPolicies { |
|
buffer.WriteString(fmt.Sprintf(" %s\n", templatedPolicy.TemplateName)) |
|
if templatedPolicy.TemplateVariables != nil && templatedPolicy.TemplateVariables.Name != "" { |
|
buffer.WriteString(fmt.Sprintf(" Name: %s\n", templatedPolicy.TemplateVariables.Name)) |
|
} |
|
if len(templatedPolicy.Datacenters) > 0 { |
|
buffer.WriteString(fmt.Sprintf(" Datacenters: %s\n", strings.Join(templatedPolicy.Datacenters, ", "))) |
|
} else { |
|
buffer.WriteString(" Datacenters: all\n") |
|
} |
|
} |
|
} |
|
|
|
return buffer.String() |
|
} |
|
|
|
func newJSONFormatter(showMeta bool) Formatter { |
|
return &jsonFormatter{showMeta} |
|
} |
|
|
|
type jsonFormatter struct { |
|
showMeta bool |
|
} |
|
|
|
func (f *jsonFormatter) FormatRole(role *api.ACLRole) (string, error) { |
|
b, err := json.MarshalIndent(role, "", " ") |
|
if err != nil { |
|
return "", fmt.Errorf("Failed to marshal role: %v", err) |
|
} |
|
return string(b), nil |
|
} |
|
|
|
func (f *jsonFormatter) FormatRoleList(roles []*api.ACLRole) (string, error) { |
|
b, err := json.MarshalIndent(roles, "", " ") |
|
if err != nil { |
|
return "", fmt.Errorf("Failed to marshal roles: %v", err) |
|
} |
|
return string(b), nil |
|
}
|
|
|