// Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: BUSL-1.1 package bindingrule import ( "bytes" "encoding/json" "fmt" "github.com/hashicorp/consul/api" ) const ( PrettyFormat string = "pretty" JSONFormat string = "json" ) // Formatter defines methods provided by bindingrule command output formatter type Formatter interface { FormatBindingRule(rule *api.ACLBindingRule) (string, error) FormatBindingRuleList(rules []*api.ACLBindingRule) (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) FormatBindingRule(rule *api.ACLBindingRule) (string, error) { var buffer bytes.Buffer buffer.WriteString(fmt.Sprintf("ID: %s\n", rule.ID)) if rule.Partition != "" { buffer.WriteString(fmt.Sprintf("Partition: %s\n", rule.Partition)) } if rule.Namespace != "" { buffer.WriteString(fmt.Sprintf("Namespace: %s\n", rule.Namespace)) } buffer.WriteString(fmt.Sprintf("AuthMethod: %s\n", rule.AuthMethod)) buffer.WriteString(fmt.Sprintf("Description: %s\n", rule.Description)) buffer.WriteString(fmt.Sprintf("BindType: %s\n", rule.BindType)) buffer.WriteString(fmt.Sprintf("BindName: %s\n", rule.BindName)) if rule.BindVars != nil && rule.BindVars.Name != "" { buffer.WriteString(fmt.Sprintf("BindVars: \n - Name: %s\n", rule.BindVars.Name)) } buffer.WriteString(fmt.Sprintf("Selector: %s\n", rule.Selector)) if f.showMeta { buffer.WriteString(fmt.Sprintf("Create Index: %d\n", rule.CreateIndex)) buffer.WriteString(fmt.Sprintf("Modify Index: %d\n", rule.ModifyIndex)) } return buffer.String(), nil } func (f *prettyFormatter) FormatBindingRuleList(rules []*api.ACLBindingRule) (string, error) { var buffer bytes.Buffer for _, rule := range rules { buffer.WriteString(f.formatBindingRuleListEntry(rule)) } return buffer.String(), nil } func (f *prettyFormatter) formatBindingRuleListEntry(rule *api.ACLBindingRule) string { var buffer bytes.Buffer buffer.WriteString(fmt.Sprintf("%s:\n", rule.ID)) if rule.Partition != "" { buffer.WriteString(fmt.Sprintf(" Partition: %s\n", rule.Partition)) } if rule.Namespace != "" { buffer.WriteString(fmt.Sprintf(" Namespace: %s\n", rule.Namespace)) } buffer.WriteString(fmt.Sprintf(" AuthMethod: %s\n", rule.AuthMethod)) buffer.WriteString(fmt.Sprintf(" Description: %s\n", rule.Description)) buffer.WriteString(fmt.Sprintf(" BindType: %s\n", rule.BindType)) buffer.WriteString(fmt.Sprintf(" BindName: %s\n", rule.BindName)) if rule.BindVars != nil && rule.BindVars.Name != "" { buffer.WriteString(fmt.Sprintf(" BindVars: \n - Name: %s\n", rule.BindVars.Name)) } buffer.WriteString(fmt.Sprintf(" Selector: %s\n", rule.Selector)) if f.showMeta { buffer.WriteString(fmt.Sprintf(" Create Index: %d\n", rule.CreateIndex)) buffer.WriteString(fmt.Sprintf(" Modify Index: %d\n", rule.ModifyIndex)) } return buffer.String() } func newJSONFormatter(showMeta bool) Formatter { return &jsonFormatter{showMeta} } type jsonFormatter struct { showMeta bool } func (f *jsonFormatter) FormatBindingRule(rule *api.ACLBindingRule) (string, error) { b, err := json.MarshalIndent(rule, "", " ") if err != nil { return "", fmt.Errorf("Failed to marshal binding rule:, %v", err) } return string(b), nil } func (f *jsonFormatter) FormatBindingRuleList(rules []*api.ACLBindingRule) (string, error) { b, err := json.MarshalIndent(rules, "", " ") if err != nil { return "", fmt.Errorf("Failed to marshal binding rules:, %v", err) } return string(b), nil }