Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provider/aws: Add validation for ECR repository name #4431

Merged
merged 2 commits into from
Jan 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions builtin/providers/aws/resource_aws_autoscaling_schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,3 @@ func resourceAwsASGScheduledActionRetrieve(d *schema.ResourceData, meta interfac

return actions.ScheduledUpdateGroupActions[0], nil
}

func validateASGScheduleTimestamp(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
_, err := time.Parse(awsAutoscalingScheduleTimeLayout, value)
if err != nil {
errors = append(errors, fmt.Errorf(
"%q cannot be parsed as iso8601 Timestamp Format", value))
}

return
}
11 changes: 0 additions & 11 deletions builtin/providers/aws/resource_aws_codedeploy_deployment_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,17 +344,6 @@ func onPremisesTagFiltersToMap(list []*codedeploy.TagFilter) []map[string]string
return result
}

// validateTagFilters confirms the "value" component of a tag filter is one of
// AWS's three allowed types.
func validateTagFilters(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if value != "KEY_ONLY" && value != "VALUE_ONLY" && value != "KEY_AND_VALUE" {
errors = append(errors, fmt.Errorf(
"%q must be one of \"KEY_ONLY\", \"VALUE_ONLY\", or \"KEY_AND_VALUE\"", k))
}
return
}

func resourceAwsCodeDeployTagFilterHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
Expand Down
27 changes: 0 additions & 27 deletions builtin/providers/aws/resource_aws_db_parameter_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"fmt"
"log"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -285,29 +284,3 @@ func buildRDSPGARN(d *schema.ResourceData, meta interface{}) (string, error) {
arn := fmt.Sprintf("arn:aws:rds:%s:%s:pg:%s", region, accountID, d.Id())
return arn, nil
}

func validateDbParamGroupName(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"only lowercase alphanumeric characters and hyphens allowed in %q", k))
}
if !regexp.MustCompile(`^[a-z]`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"first character of %q must be a letter", k))
}
if regexp.MustCompile(`--`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot contain two consecutive hyphens", k))
}
if regexp.MustCompile(`-$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot end with a hyphen", k))
}
if len(value) > 255 {
errors = append(errors, fmt.Errorf(
"%q cannot be greater than 255 characters", k))
}
return

}
15 changes: 0 additions & 15 deletions builtin/providers/aws/resource_aws_dynamodb_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -801,18 +801,3 @@ func waitForTableToBeActive(tableName string, meta interface{}) error {
return nil

}

func validateStreamViewType(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
viewTypes := map[string]bool{
"KEYS_ONLY": true,
"NEW_IMAGE": true,
"OLD_IMAGE": true,
"NEW_AND_OLD_IMAGES": true,
}

if !viewTypes[value] {
errors = append(errors, fmt.Errorf("%q be a valid DynamoDB StreamViewType", k))
}
return
}
24 changes: 0 additions & 24 deletions builtin/providers/aws/resource_aws_elb.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"fmt"
"log"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -673,29 +672,6 @@ func isLoadBalancerNotFound(err error) bool {
return ok && elberr.Code() == "LoadBalancerNotFound"
}

func validateElbName(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if !regexp.MustCompile(`^[0-9A-Za-z-]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"only alphanumeric characters and hyphens allowed in %q: %q",
k, value))
}
if len(value) > 32 {
errors = append(errors, fmt.Errorf(
"%q cannot be longer than 32 characters: %q", k, value))
}
if regexp.MustCompile(`^-`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot begin with a hyphen: %q", k, value))
}
if regexp.MustCompile(`-$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot end with a hyphen: %q", k, value))
}
return

}

func sourceSGIdByName(meta interface{}, sg, vpcId string) (string, error) {
conn := meta.(*AWSClient).ec2conn
var filters []*ec2.Filter
Expand Down
22 changes: 0 additions & 22 deletions builtin/providers/aws/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"encoding/json"
"fmt"
"regexp"
"sort"
"strings"

Expand Down Expand Up @@ -516,27 +515,6 @@ func expandResourceRecords(recs []interface{}, typeStr string) []*route53.Resour
return records
}

func validateRdsId(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"only lowercase alphanumeric characters and hyphens allowed in %q", k))
}
if !regexp.MustCompile(`^[a-z]`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"first character of %q must be a letter", k))
}
if regexp.MustCompile(`--`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot contain two consecutive hyphens", k))
}
if regexp.MustCompile(`-$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot end with a hyphen", k))
}
return
}

func expandESClusterConfig(m map[string]interface{}) *elasticsearch.ElasticsearchClusterConfig {
config := elasticsearch.ElasticsearchClusterConfig{}

Expand Down
136 changes: 136 additions & 0 deletions builtin/providers/aws/validators.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package aws

import (
"fmt"
"regexp"
"time"
)

func validateRdsId(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"only lowercase alphanumeric characters and hyphens allowed in %q", k))
}
if !regexp.MustCompile(`^[a-z]`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"first character of %q must be a letter", k))
}
if regexp.MustCompile(`--`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot contain two consecutive hyphens", k))
}
if regexp.MustCompile(`-$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot end with a hyphen", k))
}
return
}

func validateASGScheduleTimestamp(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
_, err := time.Parse(awsAutoscalingScheduleTimeLayout, value)
if err != nil {
errors = append(errors, fmt.Errorf(
"%q cannot be parsed as iso8601 Timestamp Format", value))
}

return
}

// validateTagFilters confirms the "value" component of a tag filter is one of
// AWS's three allowed types.
func validateTagFilters(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if value != "KEY_ONLY" && value != "VALUE_ONLY" && value != "KEY_AND_VALUE" {
errors = append(errors, fmt.Errorf(
"%q must be one of \"KEY_ONLY\", \"VALUE_ONLY\", or \"KEY_AND_VALUE\"", k))
}
return
}

func validateDbParamGroupName(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"only lowercase alphanumeric characters and hyphens allowed in %q", k))
}
if !regexp.MustCompile(`^[a-z]`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"first character of %q must be a letter", k))
}
if regexp.MustCompile(`--`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot contain two consecutive hyphens", k))
}
if regexp.MustCompile(`-$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot end with a hyphen", k))
}
if len(value) > 255 {
errors = append(errors, fmt.Errorf(
"%q cannot be greater than 255 characters", k))
}
return

}

func validateStreamViewType(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
viewTypes := map[string]bool{
"KEYS_ONLY": true,
"NEW_IMAGE": true,
"OLD_IMAGE": true,
"NEW_AND_OLD_IMAGES": true,
}

if !viewTypes[value] {
errors = append(errors, fmt.Errorf("%q be a valid DynamoDB StreamViewType", k))
}
return
}

func validateElbName(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if !regexp.MustCompile(`^[0-9A-Za-z-]+$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"only alphanumeric characters and hyphens allowed in %q: %q",
k, value))
}
if len(value) > 32 {
errors = append(errors, fmt.Errorf(
"%q cannot be longer than 32 characters: %q", k, value))
}
if regexp.MustCompile(`^-`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot begin with a hyphen: %q", k, value))
}
if regexp.MustCompile(`-$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot end with a hyphen: %q", k, value))
}
return

}

func validateEcrRepositoryName(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if len(value) < 2 {
errors = append(errors, fmt.Errorf(
"%q must be at least 2 characters long: %q", k, value))
}
if len(value) > 256 {
errors = append(errors, fmt.Errorf(
"%q cannot be longer than 256 characters: %q", k, value))
}

// http://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_CreateRepository.html
pattern := `^(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*$`
if !regexp.MustCompile(pattern).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q doesn't comply with restrictions (%q): %q",
k, pattern, value))
}

return
}
45 changes: 45 additions & 0 deletions builtin/providers/aws/validators_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package aws

import (
"testing"
)

func TestValidateEcrRepositoryName(t *testing.T) {
validNames := []string{
"nginx-web-app",
"project-a/nginx-web-app",
"domain.ltd/nginx-web-app",
"3chosome-thing.com/01different-pattern",
"0123456789/999999999",
"double/forward/slash",
"000000000000000",
}
for _, v := range validNames {
_, errors := validateEcrRepositoryName(v, "name")
if len(errors) != 0 {
t.Fatalf("%q should be a valid ECR repository name: %q", v, errors)
}
}

invalidNames := []string{
// length > 256
"3cho_some-thing.com/01different.-_pattern01different.-_pattern01diff" +
"erent.-_pattern01different.-_pattern01different.-_pattern01different" +
".-_pattern01different.-_pattern01different.-_pattern01different.-_pa" +
"ttern01different.-_pattern01different.-_pattern234567",
// length < 2
"i",
"special@character",
"different+special=character",
"double//slash",
"double..dot",
"/slash-at-the-beginning",
"slash-at-the-end/",
}
for _, v := range invalidNames {
_, errors := validateEcrRepositoryName(v, "name")
if len(errors) == 0 {
t.Fatalf("%q should be an invalid ECR repository name", v)
}
}
}