From 2eb6572e511b205087f9ff487a568e9433d1b493 Mon Sep 17 00:00:00 2001 From: Steve Ramage Date: Sun, 11 Aug 2024 15:18:40 -0700 Subject: [PATCH] Resolves #404 - Add template support for attributes --- docs/runbook-development.md | 48 ++++++++--------- external/completion/completion_test.go | 71 ++++++++++++++++++++++++++ external/json/to_json.go | 1 - external/resources/yaml/resources.yaml | 19 +++++++ external/runbooks/runbook_rendering.go | 3 -- external/runbooks/runbook_schema.json | 2 +- 6 files changed, 115 insertions(+), 29 deletions(-) diff --git a/docs/runbook-development.md b/docs/runbook-development.md index a3470f7..ef7f7fc 100644 --- a/docs/runbook-development.md +++ b/docs/runbook-development.md @@ -170,30 +170,30 @@ name: hello-world 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 -}} - concurrent-sleeps: - variables: - count: - type: INT - default: 2 - description: - short: "The number of sleeps" - commands: - - | - {{- range untilStep 0 .count 1}} - sleep 1 - {{- end -}} + sequential-sleeps: + 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: + type: INT + default: 2 + description: + short: "The number of sleeps" + commands: + - | + {{- range untilStep 0 .count 1}} + sleep 1 + {{- end -}} ``` It's important for all commands to be indended the same amount, and start with a `-` this will cause the entire string to be valid as a Yaml array. diff --git a/external/completion/completion_test.go b/external/completion/completion_test.go index 2078246..f9307d0 100644 --- a/external/completion/completion_test.go +++ b/external/completion/completion_test.go @@ -1,6 +1,7 @@ package completion import ( + "github.com/elasticpath/epcc-cli/external/resources" "github.com/spf13/cobra" "github.com/stretchr/testify/require" "testing" @@ -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\ }}`) +} diff --git a/external/json/to_json.go b/external/json/to_json.go index 9101858..c5e1799 100644 --- a/external/json/to_json.go +++ b/external/json/to_json.go @@ -274,6 +274,5 @@ func formatValue(v string) string { v = strings.ReplaceAll(v, `"`, `\"`) return fmt.Sprintf("\"%s\"", v) - //return fmt.Sprintf("\"%s\"", v) } } diff --git a/external/resources/yaml/resources.yaml b/external/resources/yaml/resources.yaml index aae1151..6198c55 100644 --- a/external/resources/yaml/resources.yaml +++ b/external/resources/yaml/resources.yaml @@ -183,6 +183,25 @@ account-addresses: country: type: STRING autofill: FUNC:CountryAbr +account-cart-associations: + singular-name: account-cart-association + json-api-type: account-cart-relationship + json-api-format: "legacy" + no-wrapping: true + docs: "https://elasticpath.dev/docs/commerce-cloud/carts/account-cart-associations/account-cart-associations-overview" + delete-entity: + docs: "https://elasticpath.dev/docs/commerce-cloud/carts/account-cart-associations/delete-an-association" + url: "/v2/carts/{carts}/relationships/accounts" + create-entity: + docs: "https://elasticpath.dev/docs/commerce-cloud/carts/account-cart-associations/create-an-association" + url: "/v2/carts/{carts}/relationships/accounts" + content-type: application/json + attributes: + data[n].id: + type: RESOURCE_ID:account + data[n].type: + type: ENUM:account + autofill: VALUE:account application-keys: singular-name: "application-key" json-api-type: "application_key" diff --git a/external/runbooks/runbook_rendering.go b/external/runbooks/runbook_rendering.go index 0e78306..2103240 100644 --- a/external/runbooks/runbook_rendering.go +++ b/external/runbooks/runbook_rendering.go @@ -50,13 +50,10 @@ func RenderTemplates(templateName string, rawCmd string, stringVars map[string]* return nil, fmt.Errorf("error processing variable %s, value %v is not an integer: %w", key, *val, err) } data[key] = parsedVal - data[strings.ReplaceAll(key, "-", "_")] = parsedVal } else if variableDef.Type == "STRING" { data[key] = val - data[strings.ReplaceAll(key, "-", "_")] = val } else if strings.HasPrefix(variableDef.Type, "RESOURCE_ID:") { data[key] = val - data[strings.ReplaceAll(key, "-", "_")] = val } else { return nil, fmt.Errorf("error processing variable %s, unknown type [%s] specified in template", key, variableDef.Type) } diff --git a/external/runbooks/runbook_schema.json b/external/runbooks/runbook_schema.json index a5d2bce..8ab29bb 100644 --- a/external/runbooks/runbook_schema.json +++ b/external/runbooks/runbook_schema.json @@ -63,7 +63,7 @@ "properties": { "type": { "type": "string", - "pattern": "^(STRING|URL|INT|ENUM:[a-z0-9A-Z._,-]+|FLOAT|BOOL|FILE|CURRENCY|SINGULAR_RESOURCE_TYPE|JSON_API_TYPE|RESOURCE_ID:[a-z0-9-]+|ANY)$" + "pattern": "^(STRING|URL|INT|ENUM:[a-z0-9A-Z._,-]+|FLOAT|BOOL|FILE|CURRENCY|SINGULAR_RESOURCE_TYPE|JSON_API_TYPE|RESOURCE_ID:[a-z0-9-]+)$" }, "default": { "type": ["integer", "string"],