From 39b74f8f6faee35d0d2cb539249b3b32da83cd27 Mon Sep 17 00:00:00 2001 From: Danny Schofield Date: Thu, 9 May 2024 21:57:52 -0400 Subject: [PATCH] resource: use regex replace to match the stack name for cloudformation --- resource/stack.go | 14 ++++++++++++++ resource/stack_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/resource/stack.go b/resource/stack.go index bcb0cb7..24b6f5c 100644 --- a/resource/stack.go +++ b/resource/stack.go @@ -2,6 +2,7 @@ package resource import ( "fmt" + "regexp" "strings" "time" @@ -100,6 +101,9 @@ func (s Stack) CloudformationParametersType() ([]*cloudformation.Parameter, erro return params, nil } +// CloudformationStackName returns the corresponding stack name to create in cloudformation. +// +// The name needs to match [a-zA-Z][-a-zA-Z0-9]*|arn:[-a-zA-Z0-9:/._+]* func (s Stack) CloudformationStackName() *string { // Replace: // - "/" with "-", "/" appears in the path @@ -112,6 +116,16 @@ func (s Stack) CloudformationStackName() *string { name = name + "-" + s.Region } + // Stack name needs to start with [a-zA-Z] + // Remove leading characters that are not alphabetic + firstAlphaRegex := regexp.MustCompile(`^[^a-zA-Z]*`) + name = firstAlphaRegex.ReplaceAllString(name, "") + + // Ensure the first character is alphabetic (already guaranteed by the previous step) + // Remove or replace all characters that do not match [-a-zA-Z0-9] + validCharsRegex := regexp.MustCompile(`[^-a-zA-Z0-9]+`) + name = validCharsRegex.ReplaceAllString(name, "-") + return &name } diff --git a/resource/stack_test.go b/resource/stack_test.go index 6c750aa..e61b7f4 100644 --- a/resource/stack_test.go +++ b/resource/stack_test.go @@ -41,3 +41,40 @@ func setFields(s *Stack) { } } } + +func TestCloudformationStackName(t *testing.T) { + tests := []struct { + input Stack + + want string + }{ + { + input: Stack{ + Name: "name", + Path: "path", + Region: "us-west-2", + }, + want: "name-path-us-west-2", + }, + { + input: Stack{ + Path: "./path", + Region: "us-west-2", + }, + want: "path-us-west-2", + }, + { + input: Stack{ + Name: "@danny", + Path: "./path", + Region: "us-west-2", + }, + want: "danny---path-us-west-2", + }, + } + + for _, tc := range tests { + assert.Equal(t, tc.want, *tc.input.CloudformationStackName()) + } + +}