Skip to content

Commit

Permalink
Merge pull request #5966 from ArcturusZhang/Update-Validation-VM-Name
Browse files Browse the repository at this point in the history
Update name validation rules for `azurerm_(linux|windows)_virtual_machine`
  • Loading branch information
tombuildsstuff authored Mar 17, 2020
2 parents 690d64e + 42afc59 commit 3b2f2f7
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 47 deletions.
120 changes: 76 additions & 44 deletions azurerm/internal/services/compute/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,85 @@ import (
)

func ValidateLinuxName(i interface{}, k string) (warnings []string, errors []error) {
return validateName(64)(i, k)
v, ok := i.(string)
if !ok {
errors = append(errors, fmt.Errorf("Expected %q to be a string but it wasn't!", k))
return
}

// The value must not be empty.
if strings.TrimSpace(v) == "" {
errors = append(errors, fmt.Errorf("%q must not be empty", k))
return
}

const maxLength = 64
// The value must be between 1 and 64 (Linux) characters long.
if len(v) > maxLength {
errors = append(errors, fmt.Errorf("%q can be at most %d characters, got %d", k, maxLength, len(v)))
}

if strings.HasPrefix(v, "_") {
errors = append(errors, fmt.Errorf("%q cannot begin with an underscore", k))
}

if strings.HasSuffix(v, ".") || strings.HasSuffix(v, "-") {
errors = append(errors, fmt.Errorf("%q cannot end with an period or dash", k))
}

// Azure resource names cannot contain special characters \/""[]:|<>+=;,?*@& or begin with '_' or end with '.' or '-'
specialCharacters := `\/""[]:|<>+=;,?*@&`
if strings.ContainsAny(v, specialCharacters) {
errors = append(errors, fmt.Errorf("%q cannot contain the special characters: `%s`", k, specialCharacters))
}

// The value can only contain alphanumeric characters and can start with a number.
if matched := regexp.MustCompile(`^[a-zA-Z0-9-_.]+$`).Match([]byte(v)); !matched {
errors = append(errors, fmt.Errorf("%q may only contain alphanumeric characters, dashes and underscores", k))
}

// Portal: Virtual machine name cannot contain only numbers.
if matched := regexp.MustCompile(`^\d+$`).Match([]byte(v)); matched {
errors = append(errors, fmt.Errorf("%q cannot contain only numbers", k))
}

return warnings, errors
}

func ValidateWindowsName(i interface{}, k string) (warnings []string, errors []error) {
return validateName(16)(i, k)
v, ok := i.(string)
if !ok {
errors = append(errors, fmt.Errorf("Expected %q to be a string but it wasn't!", k))
return
}

// The value must not be empty.
if strings.TrimSpace(v) == "" {
errors = append(errors, fmt.Errorf("%q must not be empty", k))
return
}

const maxLength = 15
// The value must be between 1 and 15 (Windows) characters long.
if len(v) > maxLength {
errors = append(errors, fmt.Errorf("%q can be at most %d characters, got %d", k, maxLength, len(v)))
}

if strings.HasSuffix(v, "-") {
errors = append(errors, fmt.Errorf("%q cannot end with dash", k))
}

// A windows computer name can only contain alphanumeric characters and hyphens
if matched := regexp.MustCompile(`^[a-zA-Z0-9-]+$`).Match([]byte(v)); !matched {
errors = append(errors, fmt.Errorf("%q may only contain alphanumeric characters and dashes", k))
}

// Portal: Virtual machine name cannot contain only numbers.
if matched := regexp.MustCompile(`^\d+$`).Match([]byte(v)); matched {
errors = append(errors, fmt.Errorf("%q cannot contain only numbers", k))
}

return warnings, errors
}

func ValidateScaleSetResourceID(i interface{}, k string) (s []string, es []error) {
Expand All @@ -37,48 +111,6 @@ func ValidateScaleSetResourceID(i interface{}, k string) (s []string, es []error
return
}

func validateName(maxLength int) func(i interface{}, k string) (warnings []string, errors []error) {
return func(i interface{}, k string) (warnings []string, errors []error) {
v, ok := i.(string)
if !ok {
errors = append(errors, fmt.Errorf("Expected %q to be a string but it wasn't!", k))
return
}

// The value must not be empty.
if strings.TrimSpace(v) == "" {
errors = append(errors, fmt.Errorf("%q must not be empty", k))
return
}

// The value must be between 1 and 64 (Linux) or 16 (Windows) characters long.
if len(v) >= maxLength {
errors = append(errors, fmt.Errorf("%q can be at most %d characters, got %d", k, maxLength-1, len(v)))
}

if strings.HasPrefix(v, "_") {
errors = append(errors, fmt.Errorf("%q cannot begin with an underscore", k))
}

if strings.HasSuffix(v, ".") || strings.HasSuffix(v, "-") {
errors = append(errors, fmt.Errorf("%q cannot end with an period or dash", k))
}

// Azure resource names cannot contain special characters \/""[]:|<>+=;,?*@& or begin with '_' or end with '.' or '-'
specialCharacters := `\/""[]:|<>+=;,?*@&`
if strings.ContainsAny(v, specialCharacters) {
errors = append(errors, fmt.Errorf("%q cannot contain the special characters: `%s`", k, specialCharacters))
}

// The value can only contain alphanumeric characters and cannot start with a number.
if matched := regexp.MustCompile(`^[a-zA-Z0-9-_]+$`).Match([]byte(v)); !matched {
errors = append(errors, fmt.Errorf("%q may only contain alphanumeric characters, dashes and underscores", k))
}

return
}
}

func validateDiskEncryptionSetName(i interface{}, k string) (warnings []string, errors []error) {
v, ok := i.(string)
if !ok {
Expand Down
41 changes: 38 additions & 3 deletions azurerm/internal/services/compute/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,34 @@ func TestValidateLinuxName(t *testing.T) {
input: "hello.",
expected: false,
},
{
// can have a dot in the middle
input: "hello.world",
expected: true,
},
{
// start with a number
input: "0abc",
expected: true,
},
{
// cannot contain only numbers
input: "12345",
expected: false,
},
{
// 63 chars
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghij",
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk",
expected: true,
},
{
// 64 chars
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk",
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkj",
expected: true,
},
{
// 65 chars
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkj",
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkjl",
expected: false,
},
}
Expand Down Expand Up @@ -90,6 +105,11 @@ func TestValidateWindowsName(t *testing.T) {
input: "_hello",
expected: false,
},
{
// can't contain underscore
input: "hello_world",
expected: false,
},
{
// can't end with a dash
input: "hello-",
Expand All @@ -110,6 +130,21 @@ func TestValidateWindowsName(t *testing.T) {
input: "hello.",
expected: false,
},
{
// can't contain dot
input: "hello.world",
expected: false,
},
{
// start with a number
input: "0abc",
expected: true,
},
{
// cannot contain only numbers
input: "12345",
expected: false,
},
{
// 14 chars
input: "abcdefghijklmn",
Expand Down

0 comments on commit 3b2f2f7

Please sign in to comment.