github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/builtin/providers/aws/validators.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"regexp"
     7  	"time"
     8  
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  )
    11  
    12  func validateRdsId(v interface{}, k string) (ws []string, errors []error) {
    13  	value := v.(string)
    14  	if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) {
    15  		errors = append(errors, fmt.Errorf(
    16  			"only lowercase alphanumeric characters and hyphens allowed in %q", k))
    17  	}
    18  	if !regexp.MustCompile(`^[a-z]`).MatchString(value) {
    19  		errors = append(errors, fmt.Errorf(
    20  			"first character of %q must be a letter", k))
    21  	}
    22  	if regexp.MustCompile(`--`).MatchString(value) {
    23  		errors = append(errors, fmt.Errorf(
    24  			"%q cannot contain two consecutive hyphens", k))
    25  	}
    26  	if regexp.MustCompile(`-$`).MatchString(value) {
    27  		errors = append(errors, fmt.Errorf(
    28  			"%q cannot end with a hyphen", k))
    29  	}
    30  	return
    31  }
    32  
    33  func validateASGScheduleTimestamp(v interface{}, k string) (ws []string, errors []error) {
    34  	value := v.(string)
    35  	_, err := time.Parse(awsAutoscalingScheduleTimeLayout, value)
    36  	if err != nil {
    37  		errors = append(errors, fmt.Errorf(
    38  			"%q cannot be parsed as iso8601 Timestamp Format", value))
    39  	}
    40  
    41  	return
    42  }
    43  
    44  // validateTagFilters confirms the "value" component of a tag filter is one of
    45  // AWS's three allowed types.
    46  func validateTagFilters(v interface{}, k string) (ws []string, errors []error) {
    47  	value := v.(string)
    48  	if value != "KEY_ONLY" && value != "VALUE_ONLY" && value != "KEY_AND_VALUE" {
    49  		errors = append(errors, fmt.Errorf(
    50  			"%q must be one of \"KEY_ONLY\", \"VALUE_ONLY\", or \"KEY_AND_VALUE\"", k))
    51  	}
    52  	return
    53  }
    54  
    55  func validateDbParamGroupName(v interface{}, k string) (ws []string, errors []error) {
    56  	value := v.(string)
    57  	if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) {
    58  		errors = append(errors, fmt.Errorf(
    59  			"only lowercase alphanumeric characters and hyphens allowed in %q", k))
    60  	}
    61  	if !regexp.MustCompile(`^[a-z]`).MatchString(value) {
    62  		errors = append(errors, fmt.Errorf(
    63  			"first character of %q must be a letter", k))
    64  	}
    65  	if regexp.MustCompile(`--`).MatchString(value) {
    66  		errors = append(errors, fmt.Errorf(
    67  			"%q cannot contain two consecutive hyphens", k))
    68  	}
    69  	if regexp.MustCompile(`-$`).MatchString(value) {
    70  		errors = append(errors, fmt.Errorf(
    71  			"%q cannot end with a hyphen", k))
    72  	}
    73  	if len(value) > 255 {
    74  		errors = append(errors, fmt.Errorf(
    75  			"%q cannot be greater than 255 characters", k))
    76  	}
    77  	return
    78  
    79  }
    80  
    81  func validateStreamViewType(v interface{}, k string) (ws []string, errors []error) {
    82  	value := v.(string)
    83  	viewTypes := map[string]bool{
    84  		"KEYS_ONLY":          true,
    85  		"NEW_IMAGE":          true,
    86  		"OLD_IMAGE":          true,
    87  		"NEW_AND_OLD_IMAGES": true,
    88  	}
    89  
    90  	if !viewTypes[value] {
    91  		errors = append(errors, fmt.Errorf("%q be a valid DynamoDB StreamViewType", k))
    92  	}
    93  	return
    94  }
    95  
    96  func validateElbName(v interface{}, k string) (ws []string, errors []error) {
    97  	value := v.(string)
    98  	if !regexp.MustCompile(`^[0-9A-Za-z-]+$`).MatchString(value) {
    99  		errors = append(errors, fmt.Errorf(
   100  			"only alphanumeric characters and hyphens allowed in %q: %q",
   101  			k, value))
   102  	}
   103  	if len(value) > 32 {
   104  		errors = append(errors, fmt.Errorf(
   105  			"%q cannot be longer than 32 characters: %q", k, value))
   106  	}
   107  	if regexp.MustCompile(`^-`).MatchString(value) {
   108  		errors = append(errors, fmt.Errorf(
   109  			"%q cannot begin with a hyphen: %q", k, value))
   110  	}
   111  	if regexp.MustCompile(`-$`).MatchString(value) {
   112  		errors = append(errors, fmt.Errorf(
   113  			"%q cannot end with a hyphen: %q", k, value))
   114  	}
   115  	return
   116  
   117  }
   118  
   119  func validateEcrRepositoryName(v interface{}, k string) (ws []string, errors []error) {
   120  	value := v.(string)
   121  	if len(value) < 2 {
   122  		errors = append(errors, fmt.Errorf(
   123  			"%q must be at least 2 characters long: %q", k, value))
   124  	}
   125  	if len(value) > 256 {
   126  		errors = append(errors, fmt.Errorf(
   127  			"%q cannot be longer than 256 characters: %q", k, value))
   128  	}
   129  
   130  	// http://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_CreateRepository.html
   131  	pattern := `^(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*$`
   132  	if !regexp.MustCompile(pattern).MatchString(value) {
   133  		errors = append(errors, fmt.Errorf(
   134  			"%q doesn't comply with restrictions (%q): %q",
   135  			k, pattern, value))
   136  	}
   137  
   138  	return
   139  }
   140  
   141  func validateCloudWatchEventRuleName(v interface{}, k string) (ws []string, errors []error) {
   142  	value := v.(string)
   143  	if len(value) > 64 {
   144  		errors = append(errors, fmt.Errorf(
   145  			"%q cannot be longer than 64 characters: %q", k, value))
   146  	}
   147  
   148  	// http://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_PutRule.html
   149  	pattern := `^[\.\-_A-Za-z0-9]+$`
   150  	if !regexp.MustCompile(pattern).MatchString(value) {
   151  		errors = append(errors, fmt.Errorf(
   152  			"%q doesn't comply with restrictions (%q): %q",
   153  			k, pattern, value))
   154  	}
   155  
   156  	return
   157  }
   158  
   159  func validateMaxLength(length int) schema.SchemaValidateFunc {
   160  	return func(v interface{}, k string) (ws []string, errors []error) {
   161  		value := v.(string)
   162  		if len(value) > length {
   163  			errors = append(errors, fmt.Errorf(
   164  				"%q cannot be longer than %d characters: %q", k, length, value))
   165  		}
   166  		return
   167  	}
   168  }
   169  
   170  func validateCloudWatchEventTargetId(v interface{}, k string) (ws []string, errors []error) {
   171  	value := v.(string)
   172  	if len(value) > 64 {
   173  		errors = append(errors, fmt.Errorf(
   174  			"%q cannot be longer than 64 characters: %q", k, value))
   175  	}
   176  
   177  	// http://docs.aws.amazon.com/AmazonCloudWatchEvents/latest/APIReference/API_Target.html
   178  	pattern := `^[\.\-_A-Za-z0-9]+$`
   179  	if !regexp.MustCompile(pattern).MatchString(value) {
   180  		errors = append(errors, fmt.Errorf(
   181  			"%q doesn't comply with restrictions (%q): %q",
   182  			k, pattern, value))
   183  	}
   184  
   185  	return
   186  }
   187  
   188  func validateLambdaFunctionName(v interface{}, k string) (ws []string, errors []error) {
   189  	value := v.(string)
   190  	if len(value) > 140 {
   191  		errors = append(errors, fmt.Errorf(
   192  			"%q cannot be longer than 140 characters: %q", k, value))
   193  	}
   194  	// http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html
   195  	pattern := `^(arn:aws:lambda:)?([a-z]{2}-[a-z]+-\d{1}:)?(\d{12}:)?(function:)?([a-zA-Z0-9-_]+)(:(\$LATEST|[a-zA-Z0-9-_]+))?$`
   196  	if !regexp.MustCompile(pattern).MatchString(value) {
   197  		errors = append(errors, fmt.Errorf(
   198  			"%q doesn't comply with restrictions (%q): %q",
   199  			k, pattern, value))
   200  	}
   201  
   202  	return
   203  }
   204  
   205  func validateLambdaQualifier(v interface{}, k string) (ws []string, errors []error) {
   206  	value := v.(string)
   207  	if len(value) > 128 {
   208  		errors = append(errors, fmt.Errorf(
   209  			"%q cannot be longer than 128 characters: %q", k, value))
   210  	}
   211  	// http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html
   212  	pattern := `^[a-zA-Z0-9$_]+$`
   213  	if !regexp.MustCompile(pattern).MatchString(value) {
   214  		errors = append(errors, fmt.Errorf(
   215  			"%q doesn't comply with restrictions (%q): %q",
   216  			k, pattern, value))
   217  	}
   218  
   219  	return
   220  }
   221  
   222  func validateLambdaPermissionAction(v interface{}, k string) (ws []string, errors []error) {
   223  	value := v.(string)
   224  
   225  	// http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html
   226  	pattern := `^(lambda:[*]|lambda:[a-zA-Z]+|[*])$`
   227  	if !regexp.MustCompile(pattern).MatchString(value) {
   228  		errors = append(errors, fmt.Errorf(
   229  			"%q doesn't comply with restrictions (%q): %q",
   230  			k, pattern, value))
   231  	}
   232  
   233  	return
   234  }
   235  
   236  func validateAwsAccountId(v interface{}, k string) (ws []string, errors []error) {
   237  	value := v.(string)
   238  
   239  	// http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html
   240  	pattern := `^\d{12}$`
   241  	if !regexp.MustCompile(pattern).MatchString(value) {
   242  		errors = append(errors, fmt.Errorf(
   243  			"%q doesn't look like AWS Account ID (exactly 12 digits): %q",
   244  			k, value))
   245  	}
   246  
   247  	return
   248  }
   249  
   250  func validateArn(v interface{}, k string) (ws []string, errors []error) {
   251  	value := v.(string)
   252  
   253  	// http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html
   254  	pattern := `^arn:aws:([a-zA-Z0-9\-])+:([a-z]{2}-[a-z]+-\d{1})?:(\d{12})?:(.*)$`
   255  	if !regexp.MustCompile(pattern).MatchString(value) {
   256  		errors = append(errors, fmt.Errorf(
   257  			"%q doesn't look like a valid ARN (%q): %q",
   258  			k, pattern, value))
   259  	}
   260  
   261  	return
   262  }
   263  
   264  func validatePolicyStatementId(v interface{}, k string) (ws []string, errors []error) {
   265  	value := v.(string)
   266  
   267  	if len(value) > 100 {
   268  		errors = append(errors, fmt.Errorf(
   269  			"%q cannot be longer than 100 characters: %q", k, value))
   270  	}
   271  
   272  	// http://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html
   273  	pattern := `^[a-zA-Z0-9-_]+$`
   274  	if !regexp.MustCompile(pattern).MatchString(value) {
   275  		errors = append(errors, fmt.Errorf(
   276  			"%q doesn't look like a valid statement ID (%q): %q",
   277  			k, pattern, value))
   278  	}
   279  
   280  	return
   281  }
   282  
   283  // validateCIDRNetworkAddress ensures that the string value is a valid CIDR that
   284  // represents a network address - it adds an error otherwise
   285  func validateCIDRNetworkAddress(v interface{}, k string) (ws []string, errors []error) {
   286  	value := v.(string)
   287  	_, ipnet, err := net.ParseCIDR(value)
   288  	if err != nil {
   289  		errors = append(errors, fmt.Errorf(
   290  			"%q must contain a valid CIDR, got error parsing: %s", k, err))
   291  		return
   292  	}
   293  
   294  	if ipnet == nil || value != ipnet.String() {
   295  		errors = append(errors, fmt.Errorf(
   296  			"%q must contain a valid network CIDR, expected %q, got %q",
   297  			k, ipnet, value))
   298  	}
   299  
   300  	return
   301  }
   302  
   303  func validateHTTPMethod(v interface{}, k string) (ws []string, errors []error) {
   304  	value := v.(string)
   305  	if value != "GET" && value != "HEAD" && value != "OPTIONS" && value != "PUT" && value != "POST" && value != "PATCH" && value != "DELETE" {
   306  		errors = append(errors, fmt.Errorf(
   307  			"%q must be one of 'GET', 'HEAD', 'OPTIONS', 'PUT', 'POST', 'PATCH', 'DELETE'", k))
   308  	}
   309  	return
   310  }
   311  
   312  func validateLogMetricFilterName(v interface{}, k string) (ws []string, errors []error) {
   313  	value := v.(string)
   314  
   315  	if len(value) > 512 {
   316  		errors = append(errors, fmt.Errorf(
   317  			"%q cannot be longer than 512 characters: %q", k, value))
   318  	}
   319  
   320  	// http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutMetricFilter.html
   321  	pattern := `^[^:*]+$`
   322  	if !regexp.MustCompile(pattern).MatchString(value) {
   323  		errors = append(errors, fmt.Errorf(
   324  			"%q isn't a valid log metric name (must not contain colon nor asterisk): %q",
   325  			k, value))
   326  	}
   327  
   328  	return
   329  }
   330  
   331  func validateLogMetricFilterTransformationName(v interface{}, k string) (ws []string, errors []error) {
   332  	value := v.(string)
   333  
   334  	if len(value) > 255 {
   335  		errors = append(errors, fmt.Errorf(
   336  			"%q cannot be longer than 255 characters: %q", k, value))
   337  	}
   338  
   339  	// http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_MetricTransformation.html
   340  	pattern := `^[^:*$]*$`
   341  	if !regexp.MustCompile(pattern).MatchString(value) {
   342  		errors = append(errors, fmt.Errorf(
   343  			"%q isn't a valid log metric transformation name (must not contain"+
   344  				" colon, asterisk nor dollar sign): %q",
   345  			k, value))
   346  	}
   347  
   348  	return
   349  }
   350  
   351  func validateLogGroupName(v interface{}, k string) (ws []string, errors []error) {
   352  	value := v.(string)
   353  
   354  	if len(value) > 512 {
   355  		errors = append(errors, fmt.Errorf(
   356  			"%q cannot be longer than 512 characters: %q", k, value))
   357  	}
   358  
   359  	// http://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html
   360  	pattern := `^[\.\-_/#A-Za-z0-9]+$`
   361  	if !regexp.MustCompile(pattern).MatchString(value) {
   362  		errors = append(errors, fmt.Errorf(
   363  			"%q isn't a valid log group name (alphanumeric characters, underscores,"+
   364  				" hyphens, slashes, hash signs and dots are allowed): %q",
   365  			k, value))
   366  	}
   367  
   368  	return
   369  }