Skip to content

Commit

Permalink
Resolves #404 - Add template support for attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
steve-r-west committed Aug 20, 2024
1 parent c09ece5 commit 06f7238
Show file tree
Hide file tree
Showing 15 changed files with 330 additions and 38 deletions.
11 changes: 6 additions & 5 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,11 +185,12 @@ func NewCreateCommand(parentCmd *cobra.Command) func() {
})
} else { // This is an attribute value
return completion.Complete(completion.Request{
Type: completion.CompleteAttributeValue,
Resource: resource,
Verb: completion.Create,
Attribute: args[len(args)-1],
ToComplete: toComplete,
Type: completion.CompleteAttributeValue,
Resource: resource,
Verb: completion.Create,
Attribute: args[len(args)-1],
ToComplete: toComplete,
AllowTemplates: true,
})
}
} else {
Expand Down
11 changes: 6 additions & 5 deletions cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,12 @@ func NewDeleteCommand(parentCmd *cobra.Command) func() {
})
} else { // This is an attribute value
return completion.Complete(completion.Request{
Type: completion.CompleteAttributeValue,
Resource: resource,
Verb: completion.Delete,
Attribute: args[len(args)-1],
ToComplete: toComplete,
Type: completion.CompleteAttributeValue,
Resource: resource,
Verb: completion.Delete,
Attribute: args[len(args)-1],
ToComplete: toComplete,
AllowTemplates: true,
})
}
}
Expand Down
5 changes: 4 additions & 1 deletion cmd/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,9 @@ epcc %s %s%s key [] => %s
# To send a nested object use the . character to nest values deeper.
epcc %s %s%s key.some.child hello key.some.other goodbye => %s
`,
# Attributes can also be generated using Go templates and Sprig (https://masterminds.github.io/sprig/) functions.
epcc %s %s%s key 'Test {{ randAlphaNum 6 | upper }} Value' => %s`,
verb, resource.SingularName, id, toJsonExample([]string{"key", "b"}, resource),
verb, resource.SingularName, id, toJsonExample([]string{"key", "1"}, resource),
verb, resource.SingularName, id, toJsonExample([]string{"key", "\"1\""}, resource),
Expand All @@ -310,6 +312,7 @@ epcc %s %s%s key.some.child hello key.some.other goodbye => %s
verb, resource.SingularName, id, toJsonExample([]string{"key[0]", "a", "key[1]", "true"}, resource),
verb, resource.SingularName, id, toJsonExample([]string{"key", "[]"}, resource),
verb, resource.SingularName, id, toJsonExample([]string{"key.some.child", "hello", "key.some.other", "goodbye"}, resource),
verb, resource.SingularName, id, toJsonExample([]string{"key", "Test {{ randAlphaNum 6 | upper }} Value"}, resource),
)
}

Expand Down
11 changes: 6 additions & 5 deletions cmd/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,11 +428,12 @@ var loginAccountManagement = &cobra.Command{
})
} else {
return completion.Complete(completion.Request{
Type: completion.CompleteAttributeValue,
Verb: completion.Create,
Resource: res,
Attributes: usedAttributes,
ToComplete: toComplete,
Type: completion.CompleteAttributeValue,
Verb: completion.Create,
Resource: res,
Attributes: usedAttributes,
ToComplete: toComplete,
AllowTemplates: true,
})
}

Expand Down
1 change: 0 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ func Execute() {

os.Exit(1)
} else {

os.Exit(0)
}
}
Expand Down
2 changes: 0 additions & 2 deletions cmd/runbooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,11 +421,9 @@ func processRunbookVariablesOnCommand(runbookActionRunActionCommand *cobra.Comma
}
} else {
description := ""

if variable.Description != nil {
description = variable.Description.Short
}

runbookActionRunActionCommand.Flags().StringVar(runbookStringArguments[key], key, variable.Default, description)
}

Expand Down
11 changes: 6 additions & 5 deletions cmd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,12 @@ func NewUpdateCommand(parentCmd *cobra.Command) func() {
})
} else { // This is an attribute value
return completion.Complete(completion.Request{
Type: completion.CompleteAttributeValue,
Resource: resource,
Verb: completion.Update,
Attribute: args[len(args)-1],
ToComplete: toComplete,
Type: completion.CompleteAttributeValue,
Resource: resource,
Verb: completion.Update,
Attribute: args[len(args)-1],
ToComplete: toComplete,
AllowTemplates: true,
})
}
} else {
Expand Down
22 changes: 11 additions & 11 deletions docs/runbook-development.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,17 @@ description:
short: "A hello world runbook"
actions:
sequential-sleeps:
variables:
count:
type: INT
default: 2
description:
short: "The number of sleeps"
commands:
- |2
{{- range untilStep 0 .count 1}}
- sleep 1
{{- end -}}
variables:
count:
type: INT
default: 2
description:
short: "The number of sleeps"
commands:
- |2
{{- range untilStep 0 .count 1}}
- sleep 1
{{- end -}}
concurrent-sleeps:
variables:
count:
Expand Down
80 changes: 78 additions & 2 deletions external/completion/completion.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package completion

import (
"fmt"
"github.com/elasticpath/epcc-cli/external/aliases"
"github.com/elasticpath/epcc-cli/external/resources"
"github.com/spf13/cobra"
"os"
"regexp"
"strconv"
"strings"
Expand Down Expand Up @@ -48,8 +50,9 @@ type Request struct {
QueryParam string
Header string
// The current string argument being completed
ToComplete string
NoAliases bool
ToComplete string
NoAliases bool
AllowTemplates bool
}

func Complete(c Request) ([]string, cobra.ShellCompDirective) {
Expand Down Expand Up @@ -295,6 +298,79 @@ func Complete(c Request) ([]string, cobra.ShellCompDirective) {
results = append(results, supportedFileTypes...)
}
}

if c.AllowTemplates {
lastPipe := strings.LastIndex(c.ToComplete, "|")
prefix := ""
if lastPipe == -1 {
prefix = "{{ "
} else {
prefix = c.ToComplete[0:lastPipe+1] + " "
}

myResults := []string{}
myResults = append(myResults,
prefix+"date",
prefix+"now",
prefix+"randAlphaNum",
prefix+"randAlpha",
prefix+"randAscii",
prefix+"randNumeric",
prefix+"randAlphaNum",
prefix+"randAlpha",
prefix+"randAscii",
prefix+"randNumeric",
prefix+"pseudoRandAlphaNum",
prefix+"pseudoRandAlpha",
prefix+"pseudoRandNumeric",
prefix+"pseudoRandString",
prefix+"pseudoRandInt",
prefix+"uuidv4",
prefix+"duration",
)

if prefix != "{{ " {
// Functions that make sense as continuations
myResults = append(myResults,
prefix+"trim",
prefix+"trimAll",
prefix+"trimSuffix",
prefix+"trimPrefix",
prefix+"upper",
prefix+"lower",
prefix+"title",
prefix+"repeat",
prefix+"substr",
prefix+"nospace",
prefix+"trunc",
prefix+"abbrev",
prefix+"initials",
prefix+"wrap",
prefix+"cat",
prefix+"replace",
prefix+"snakecase",
prefix+"camelcase",
prefix+"kebabcase",
prefix+"swapcase",
prefix+"shufflecase",
)
}

re := regexp.MustCompile(`env\s+[A-Za-z]*\s*$`)
if re.MatchString(c.ToComplete) {
for _, v := range os.Environ() {
myResults = append(myResults,
fmt.Sprintf("%venv \"%v\"", prefix, strings.Split(v, "=")[0]),
)
}
} else {
myResults = append(myResults, prefix+"env")
}
//myResults = append(myResults, strings.TrimSuffix(c.ToComplete, " ")+" }}", strings.TrimSuffix(c.ToComplete, " ")+" |")
for _, r := range myResults {
results = append(results, r+" |", r+" }}")
}
}
}
}

Expand Down
71 changes: 71 additions & 0 deletions external/completion/completion_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package completion

import (
"github.com/elasticpath/epcc-cli/external/resources"
"github.com/spf13/cobra"
"github.com/stretchr/testify/require"
"testing"
Expand Down Expand Up @@ -72,3 +73,73 @@ func TestHeaderValueWithNonNilValueCompletes(t *testing.T) {
require.Equal(t, compDir, cobra.ShellCompDirectiveNoFileComp)
require.Contains(t, completions, "USD")
}

func TestAttributeValueWithNoTemplating(t *testing.T) {
// Fixture Setup
toComplete := ""
acct := resources.MustGetResourceByName("password-profiles")
request := Request{
Type: CompleteAttributeValue,
Verb: Create,
ToComplete: toComplete,
Attribute: "username_format",
Resource: acct,
}

// Exercise SUT
completions, compDir := Complete(request)

// Verify Results
require.Equal(t, compDir, cobra.ShellCompDirectiveNoFileComp)
require.Contains(t, completions, "any")
require.Contains(t, completions, "email")
require.Equal(t, 2, len(completions))
}

func TestAttributeValueWithTemplating(t *testing.T) {
// Fixture Setup
toComplete := ""
acct := resources.MustGetResourceByName("password-profiles")
request := Request{
Type: CompleteAttributeValue,
Verb: Create,
ToComplete: toComplete,
Attribute: "username_format",
Resource: acct,
AllowTemplates: true,
}

// Exercise SUT
completions, compDir := Complete(request)

// Verify Results
require.Equal(t, compDir, cobra.ShellCompDirectiveNoFileComp)
require.Contains(t, completions, "any")
require.Contains(t, completions, "email")
require.Contains(t, completions, `{{\ randAlphaNum\ |`)
require.Contains(t, completions, `{{\ randAlphaNum\ }}`)
}

func TestAttributeValueWithTemplatingAndPipe(t *testing.T) {
// Fixture Setup
toComplete := "{{ randAlphaNum 3 | "
acct := resources.MustGetResourceByName("password-profiles")
request := Request{
Type: CompleteAttributeValue,
Verb: Create,
ToComplete: toComplete,
Attribute: "username_format",
Resource: acct,
AllowTemplates: true,
}

// Exercise SUT
completions, compDir := Complete(request)

// Verify Results
require.Equal(t, compDir, cobra.ShellCompDirectiveNoFileComp)
require.Contains(t, completions, "any")
require.Contains(t, completions, "email")
require.Contains(t, completions, `{{\ randAlphaNum\ 3\ |\ upper\ |`)
require.Contains(t, completions, `{{\ randAlphaNum\ 3\ |\ lower\ }}`)
}
7 changes: 7 additions & 0 deletions external/json/to_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"github.com/elasticpath/epcc-cli/external/aliases"
"github.com/elasticpath/epcc-cli/external/resources"
"github.com/elasticpath/epcc-cli/external/templates"
"github.com/itchyny/gojq"
log "github.com/sirupsen/logrus"
"regexp"
Expand Down Expand Up @@ -53,6 +54,9 @@ func toJsonObject(args []string, noWrapping bool, compliant bool, attributes map
key := args[i]
val := args[i+1]

// Try and process the argument as a helm template
val = templates.Render(val)

jsonKey := key
switch {
case key == "type" || key == "id":
Expand Down Expand Up @@ -265,6 +269,9 @@ func formatValue(v string) string {
} else if match, _ := regexp.MatchString("^\\[\\]$", v); match {
return v
} else {
v = strings.ReplaceAll(v, "\\", "\\\\")
v = strings.ReplaceAll(v, `"`, `\"`)

return fmt.Sprintf("\"%s\"", v)
}
}
Loading

0 comments on commit 06f7238

Please sign in to comment.