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 }