Validate stack tag names (#3804)
* added regex to validate stack tag names * added tests
This commit is contained in:
parent
b6b313821c
commit
4c8237aa77
|
@ -31,17 +31,32 @@ func validateStackName(s string) error {
|
|||
return errors.New("a stack name may only contain alphanumeric, hyphens, underscores, or periods")
|
||||
}
|
||||
|
||||
// validateStackTagName checks if s is a valid stack tag name, otherwise returns a descriptive error.
|
||||
// This should match the stack naming rules enforced by the Pulumi Service.
|
||||
func validateStackTagName(s string) error {
|
||||
const maxTagName = 40
|
||||
|
||||
if len(s) == 0 {
|
||||
return errors.Errorf("invalid stack tag %q", s)
|
||||
}
|
||||
if len(s) > maxTagName {
|
||||
return errors.Errorf("stack tag %q is too long (max length %d characters)", s, maxTagName)
|
||||
}
|
||||
|
||||
var tagNameRE = regexp.MustCompile("^[a-zA-Z0-9-_.:]{1,40}$")
|
||||
if tagNameRE.MatchString(s) {
|
||||
return nil
|
||||
}
|
||||
return errors.New("stack tag names may only contain alphanumerics, hyphens, underscores, periods, or colons")
|
||||
}
|
||||
|
||||
// ValidateStackTags validates the tag names and values.
|
||||
func ValidateStackTags(tags map[apitype.StackTagName]string) error {
|
||||
const maxTagName = 40
|
||||
const maxTagValue = 256
|
||||
|
||||
for t, v := range tags {
|
||||
if len(t) == 0 {
|
||||
return errors.Errorf("invalid stack tag %q", t)
|
||||
}
|
||||
if len(t) > maxTagName {
|
||||
return errors.Errorf("stack tag %q is too long (max length %d characters)", t, maxTagName)
|
||||
if err := validateStackTagName(t); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(v) > maxTagValue {
|
||||
return errors.Errorf("stack tag %q value is too long (max length %d characters)", t, maxTagValue)
|
||||
|
@ -59,7 +74,7 @@ func ValidateStackProperties(stack string, tags map[apitype.StackTagName]string)
|
|||
return errors.Errorf("stack name too long (max length %d characters)", maxStackName)
|
||||
}
|
||||
if err := validateStackName(stack); err != nil {
|
||||
return errors.Wrapf(err, "invalid stack name")
|
||||
return err
|
||||
}
|
||||
|
||||
// Ensure tag values won't be rejected by the Pulumi Service. We do not validate that their
|
||||
|
|
79
pkg/util/validation/stack_test.go
Normal file
79
pkg/util/validation/stack_test.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/pulumi/pulumi/pkg/apitype"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestValidateStackTag(t *testing.T) {
|
||||
t.Run("valid tags", func(t *testing.T) {
|
||||
names := []string{
|
||||
"tag-name",
|
||||
"-",
|
||||
"..",
|
||||
"foo:bar:baz",
|
||||
"__underscores__",
|
||||
"AaBb123",
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
tags := map[apitype.StackTagName]string{
|
||||
name: "tag-value",
|
||||
}
|
||||
|
||||
err := ValidateStackTags(tags)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("invalid stack tag names", func(t *testing.T) {
|
||||
var names = []string{
|
||||
"tag!",
|
||||
"something with spaces",
|
||||
"escape\nsequences\there",
|
||||
"😄",
|
||||
"foo***bar",
|
||||
}
|
||||
|
||||
for _, name := range names {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
tags := map[apitype.StackTagName]string{
|
||||
name: "tag-value",
|
||||
}
|
||||
|
||||
err := ValidateStackTags(tags)
|
||||
assert.Error(t, err)
|
||||
msg := "stack tag names may only contain alphanumerics, hyphens, underscores, periods, or colons"
|
||||
assert.Equal(t, err.Error(), msg)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("too long tag name", func(t *testing.T) {
|
||||
tags := map[apitype.StackTagName]string{
|
||||
strings.Repeat("v", 41): "tag-value",
|
||||
}
|
||||
|
||||
err := ValidateStackTags(tags)
|
||||
assert.Error(t, err)
|
||||
msg := fmt.Sprintf("stack tag %q is too long (max length %d characters)", strings.Repeat("v", 41), 40)
|
||||
assert.Equal(t, err.Error(), msg)
|
||||
})
|
||||
|
||||
t.Run("too long tag value", func(t *testing.T) {
|
||||
tags := map[apitype.StackTagName]string{
|
||||
"tag-name": strings.Repeat("v", 257),
|
||||
}
|
||||
|
||||
err := ValidateStackTags(tags)
|
||||
assert.Error(t, err)
|
||||
msg := fmt.Sprintf("stack tag %q value is too long (max length %d characters)", "tag-name", 256)
|
||||
assert.Equal(t, err.Error(), msg)
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue