Merge pull request #4431 from TimeIncOSS/f-aws-validators
provider/aws: Add validation for ECR repository name
This commit is contained in:
commit
2edc25e868
|
@ -176,14 +176,3 @@ func resourceAwsASGScheduledActionRetrieve(d *schema.ResourceData, meta interfac
|
||||||
|
|
||||||
return actions.ScheduledUpdateGroupActions[0], nil
|
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
|
|
||||||
}
|
|
||||||
|
|
|
@ -344,17 +344,6 @@ func onPremisesTagFiltersToMap(list []*codedeploy.TagFilter) []map[string]string
|
||||||
return result
|
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 {
|
func resourceAwsCodeDeployTagFilterHash(v interface{}) int {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
m := v.(map[string]interface{})
|
m := v.(map[string]interface{})
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -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())
|
arn := fmt.Sprintf("arn:aws:rds:%s:%s:pg:%s", region, accountID, d.Id())
|
||||||
return arn, nil
|
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
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -833,18 +833,3 @@ func waitForTableToBeActive(tableName string, meta interface{}) error {
|
||||||
return nil
|
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
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -673,29 +672,6 @@ func isLoadBalancerNotFound(err error) bool {
|
||||||
return ok && elberr.Code() == "LoadBalancerNotFound"
|
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) {
|
func sourceSGIdByName(meta interface{}, sg, vpcId string) (string, error) {
|
||||||
conn := meta.(*AWSClient).ec2conn
|
conn := meta.(*AWSClient).ec2conn
|
||||||
var filters []*ec2.Filter
|
var filters []*ec2.Filter
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -516,27 +515,6 @@ func expandResourceRecords(recs []interface{}, typeStr string) []*route53.Resour
|
||||||
return records
|
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 {
|
func expandESClusterConfig(m map[string]interface{}) *elasticsearch.ElasticsearchClusterConfig {
|
||||||
config := elasticsearch.ElasticsearchClusterConfig{}
|
config := elasticsearch.ElasticsearchClusterConfig{}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue