github.com/jd3nn1s/terraform@v0.9.6-0.20170906225847-13878347b7a1/helper/validation/validation.go (about)

     1  package validation
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"regexp"
     7  	"strings"
     8  
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  	"github.com/hashicorp/terraform/helper/structure"
    11  )
    12  
    13  // IntBetween returns a SchemaValidateFunc which tests if the provided value
    14  // is of type int and is between min and max (inclusive)
    15  func IntBetween(min, max int) schema.SchemaValidateFunc {
    16  	return func(i interface{}, k string) (s []string, es []error) {
    17  		v, ok := i.(int)
    18  		if !ok {
    19  			es = append(es, fmt.Errorf("expected type of %s to be int", k))
    20  			return
    21  		}
    22  
    23  		if v < min || v > max {
    24  			es = append(es, fmt.Errorf("expected %s to be in the range (%d - %d), got %d", k, min, max, v))
    25  			return
    26  		}
    27  
    28  		return
    29  	}
    30  }
    31  
    32  // IntAtLeast returns a SchemaValidateFunc which tests if the provided value
    33  // is of type int and is at least min (inclusive)
    34  func IntAtLeast(min int) schema.SchemaValidateFunc {
    35  	return func(i interface{}, k string) (s []string, es []error) {
    36  		v, ok := i.(int)
    37  		if !ok {
    38  			es = append(es, fmt.Errorf("expected type of %s to be int", k))
    39  			return
    40  		}
    41  
    42  		if v < min {
    43  			es = append(es, fmt.Errorf("expected %s to be at least (%d), got %d", k, min, v))
    44  			return
    45  		}
    46  
    47  		return
    48  	}
    49  }
    50  
    51  // IntAtMost returns a SchemaValidateFunc which tests if the provided value
    52  // is of type int and is at most max (inclusive)
    53  func IntAtMost(max int) schema.SchemaValidateFunc {
    54  	return func(i interface{}, k string) (s []string, es []error) {
    55  		v, ok := i.(int)
    56  		if !ok {
    57  			es = append(es, fmt.Errorf("expected type of %s to be int", k))
    58  			return
    59  		}
    60  
    61  		if v > max {
    62  			es = append(es, fmt.Errorf("expected %s to be at most (%d), got %d", k, max, v))
    63  			return
    64  		}
    65  
    66  		return
    67  	}
    68  }
    69  
    70  // StringInSlice returns a SchemaValidateFunc which tests if the provided value
    71  // is of type string and matches the value of an element in the valid slice
    72  // will test with in lower case if ignoreCase is true
    73  func StringInSlice(valid []string, ignoreCase bool) schema.SchemaValidateFunc {
    74  	return func(i interface{}, k string) (s []string, es []error) {
    75  		v, ok := i.(string)
    76  		if !ok {
    77  			es = append(es, fmt.Errorf("expected type of %s to be string", k))
    78  			return
    79  		}
    80  
    81  		for _, str := range valid {
    82  			if v == str || (ignoreCase && strings.ToLower(v) == strings.ToLower(str)) {
    83  				return
    84  			}
    85  		}
    86  
    87  		es = append(es, fmt.Errorf("expected %s to be one of %v, got %s", k, valid, v))
    88  		return
    89  	}
    90  }
    91  
    92  // StringLenBetween returns a SchemaValidateFunc which tests if the provided value
    93  // is of type string and has length between min and max (inclusive)
    94  func StringLenBetween(min, max int) schema.SchemaValidateFunc {
    95  	return func(i interface{}, k string) (s []string, es []error) {
    96  		v, ok := i.(string)
    97  		if !ok {
    98  			es = append(es, fmt.Errorf("expected type of %s to be string", k))
    99  			return
   100  		}
   101  		if len(v) < min || len(v) > max {
   102  			es = append(es, fmt.Errorf("expected length of %s to be in the range (%d - %d), got %s", k, min, max, v))
   103  		}
   104  		return
   105  	}
   106  }
   107  
   108  // CIDRNetwork returns a SchemaValidateFunc which tests if the provided value
   109  // is of type string, is in valid CIDR network notation, and has significant bits between min and max (inclusive)
   110  func CIDRNetwork(min, max int) schema.SchemaValidateFunc {
   111  	return func(i interface{}, k string) (s []string, es []error) {
   112  		v, ok := i.(string)
   113  		if !ok {
   114  			es = append(es, fmt.Errorf("expected type of %s to be string", k))
   115  			return
   116  		}
   117  
   118  		_, ipnet, err := net.ParseCIDR(v)
   119  		if err != nil {
   120  			es = append(es, fmt.Errorf(
   121  				"expected %s to contain a valid CIDR, got: %s with err: %s", k, v, err))
   122  			return
   123  		}
   124  
   125  		if ipnet == nil || v != ipnet.String() {
   126  			es = append(es, fmt.Errorf(
   127  				"expected %s to contain a valid network CIDR, expected %s, got %s",
   128  				k, ipnet, v))
   129  		}
   130  
   131  		sigbits, _ := ipnet.Mask.Size()
   132  		if sigbits < min || sigbits > max {
   133  			es = append(es, fmt.Errorf(
   134  				"expected %q to contain a network CIDR with between %d and %d significant bits, got: %d",
   135  				k, min, max, sigbits))
   136  		}
   137  
   138  		return
   139  	}
   140  }
   141  
   142  // ValidateJsonString is a SchemaValidateFunc which tests to make sure the
   143  // supplied string is valid JSON.
   144  func ValidateJsonString(v interface{}, k string) (ws []string, errors []error) {
   145  	if _, err := structure.NormalizeJsonString(v); err != nil {
   146  		errors = append(errors, fmt.Errorf("%q contains an invalid JSON: %s", k, err))
   147  	}
   148  	return
   149  }
   150  
   151  // ValidateListUniqueStrings is a ValidateFunc that ensures a list has no
   152  // duplicate items in it. It's useful for when a list is needed over a set
   153  // because order matters, yet the items still need to be unique.
   154  func ValidateListUniqueStrings(v interface{}, k string) (ws []string, errors []error) {
   155  	for n1, v1 := range v.([]interface{}) {
   156  		for n2, v2 := range v.([]interface{}) {
   157  			if v1.(string) == v2.(string) && n1 != n2 {
   158  				errors = append(errors, fmt.Errorf("%q: duplicate entry - %s", k, v1.(string)))
   159  			}
   160  		}
   161  	}
   162  	return
   163  }
   164  
   165  // ValidateRegexp returns a SchemaValidateFunc which tests to make sure the
   166  // supplied string is a valid regular expression.
   167  func ValidateRegexp(v interface{}, k string) (ws []string, errors []error) {
   168  	if _, err := regexp.Compile(v.(string)); err != nil {
   169  		errors = append(errors, fmt.Errorf("%q: %s", k, err))
   170  	}
   171  	return
   172  }