-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NET-5334] Added CLI commands for templated policies (#18816)
- Loading branch information
1 parent
8021226
commit 1afeb6e
Showing
27 changed files
with
1,352 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
```release-note:feature | ||
cli: Add `consul acl templated-policy` commands to read, list and preview templated policies. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package templatedpolicy | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"sort" | ||
|
||
"github.com/hashicorp/consul/api" | ||
) | ||
|
||
const ( | ||
PrettyFormat string = "pretty" | ||
JSONFormat string = "json" | ||
WhitespaceIndent = "\t" | ||
) | ||
|
||
// Formatter defines methods provided by templated-policy command output formatter | ||
type Formatter interface { | ||
FormatTemplatedPolicy(policy api.ACLTemplatedPolicyResponse) (string, error) | ||
FormatTemplatedPolicyList(policies map[string]api.ACLTemplatedPolicyResponse) (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: %q", format) | ||
} | ||
|
||
return formatter, err | ||
} | ||
|
||
func newPrettyFormatter(showMeta bool) Formatter { | ||
return &prettyFormatter{showMeta} | ||
} | ||
|
||
func newJSONFormatter(showMeta bool) Formatter { | ||
return &jsonFormatter{showMeta} | ||
} | ||
|
||
type prettyFormatter struct { | ||
showMeta bool | ||
} | ||
|
||
// FormatTemplatedPolicy displays template name, input variables and example usages. When | ||
// showMeta is true, we display raw template code and schema. | ||
// This implementation is a conscious choice as we know builtin variables we know every required/optional input variables | ||
// so we can just hardcode this. | ||
// In the future, when we implement user defined templated policies, we will move this to some sort of schema parsing. | ||
// This implementation allows us to move forward without limiting ourselves when implementing user defined templated policies. | ||
func (f *prettyFormatter) FormatTemplatedPolicy(templatedPolicy api.ACLTemplatedPolicyResponse) (string, error) { | ||
var buffer bytes.Buffer | ||
|
||
buffer.WriteString(fmt.Sprintf("Name: %s\n", templatedPolicy.TemplateName)) | ||
|
||
buffer.WriteString("Input variables:") | ||
switch templatedPolicy.TemplateName { | ||
case api.ACLTemplatedPolicyServiceName: | ||
buffer.WriteString(fmt.Sprintf("\n%sName: String - Required - The name of the service.\n", WhitespaceIndent)) | ||
buffer.WriteString("Example usage:\n") | ||
buffer.WriteString(WhitespaceIndent + "consul acl token create -templated-policy builtin/service -var name:api\n") | ||
case api.ACLTemplatedPolicyNodeName: | ||
buffer.WriteString(fmt.Sprintf("\n%sName: String - Required - The node name.\n", WhitespaceIndent)) | ||
buffer.WriteString("Example usage:\n") | ||
buffer.WriteString(fmt.Sprintf("%sconsul acl token create -templated-policy builtin/node -var name:node-1\n", WhitespaceIndent)) | ||
case api.ACLTemplatedPolicyDNSName: | ||
buffer.WriteString(" None\n") | ||
buffer.WriteString("Example usage:\n") | ||
buffer.WriteString(fmt.Sprintf("%sconsul acl token create -templated-policy builtin/dns\n", WhitespaceIndent)) | ||
default: | ||
buffer.WriteString(" None\n") | ||
} | ||
|
||
if f.showMeta { | ||
if templatedPolicy.Schema != "" { | ||
buffer.WriteString(fmt.Sprintf("Schema:\n%s\n\n", templatedPolicy.Schema)) | ||
} | ||
buffer.WriteString(fmt.Sprintf("Raw Template:\n%s\n", templatedPolicy.Template)) | ||
} | ||
|
||
return buffer.String(), nil | ||
} | ||
|
||
func (f *prettyFormatter) FormatTemplatedPolicyList(policies map[string]api.ACLTemplatedPolicyResponse) (string, error) { | ||
var buffer bytes.Buffer | ||
|
||
templateNames := make([]string, 0, len(policies)) | ||
for _, templatedPolicy := range policies { | ||
templateNames = append(templateNames, templatedPolicy.TemplateName) | ||
} | ||
|
||
//ensure the list is consistently sorted by strings | ||
sort.Strings(templateNames) | ||
for _, name := range templateNames { | ||
buffer.WriteString(fmt.Sprintf("%s\n", name)) | ||
} | ||
|
||
return buffer.String(), nil | ||
} | ||
|
||
type jsonFormatter struct { | ||
showMeta bool | ||
} | ||
|
||
func (f *jsonFormatter) FormatTemplatedPolicy(templatedPolicy api.ACLTemplatedPolicyResponse) (string, error) { | ||
b, err := json.MarshalIndent(templatedPolicy, "", " ") | ||
if err != nil { | ||
return "", fmt.Errorf("failed to marshal templated policy: %v", err) | ||
} | ||
return string(b), nil | ||
} | ||
|
||
func (f *jsonFormatter) FormatTemplatedPolicyList(templatedPolicies map[string]api.ACLTemplatedPolicyResponse) (string, error) { | ||
b, err := json.MarshalIndent(templatedPolicies, "", " ") | ||
if err != nil { | ||
return "", fmt.Errorf("failed to marshal templated policies: %v", err) | ||
} | ||
return string(b), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
//go:build !consulent | ||
// +build !consulent | ||
|
||
package templatedpolicy | ||
|
||
import "testing" | ||
|
||
func TestFormatTemplatedPolicy(t *testing.T) { | ||
testFormatTemplatedPolicy(t, "FormatTemplatedPolicy/ce") | ||
} | ||
|
||
func TestFormatTemplatedPolicyList(t *testing.T) { | ||
testFormatTemplatedPolicyList(t, "FormatTemplatedPolicyList/ce") | ||
} |
Oops, something went wrong.