diff options
author | Jake Champlin <jake@gnu.space> | 2017-06-09 17:54:32 +0000 |
---|---|---|
committer | Jake Champlin <jake@gnu.space> | 2017-06-09 17:54:32 +0000 |
commit | 9b12e4fe6f3c95986f1f3ec791636c58ca7e7583 (patch) | |
tree | 38f5f12bec0e488a12f0459a7356e6b7de7d8f84 /vendor/github.com/hashicorp/terraform/helper | |
parent | cec3de8a3bcaffd21dedd1bf42da4b490cae7e16 (diff) | |
download | terraform-provider-statuscake-9b12e4fe6f3c95986f1f3ec791636c58ca7e7583.tar.gz terraform-provider-statuscake-9b12e4fe6f3c95986f1f3ec791636c58ca7e7583.tar.zst terraform-provider-statuscake-9b12e4fe6f3c95986f1f3ec791636c58ca7e7583.zip |
Transfer of provider code
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper')
11 files changed, 178 insertions, 306 deletions
diff --git a/vendor/github.com/hashicorp/terraform/helper/acctest/acctest.go b/vendor/github.com/hashicorp/terraform/helper/acctest/acctest.go deleted file mode 100644 index 9d31031..0000000 --- a/vendor/github.com/hashicorp/terraform/helper/acctest/acctest.go +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | // Package acctest contains for Terraform Acceptance Tests | ||
2 | package acctest | ||
diff --git a/vendor/github.com/hashicorp/terraform/helper/acctest/random.go b/vendor/github.com/hashicorp/terraform/helper/acctest/random.go deleted file mode 100644 index 3ddc078..0000000 --- a/vendor/github.com/hashicorp/terraform/helper/acctest/random.go +++ /dev/null | |||
@@ -1,93 +0,0 @@ | |||
1 | package acctest | ||
2 | |||
3 | import ( | ||
4 | "bufio" | ||
5 | "bytes" | ||
6 | crand "crypto/rand" | ||
7 | "crypto/rsa" | ||
8 | "crypto/x509" | ||
9 | "encoding/pem" | ||
10 | "fmt" | ||
11 | "math/rand" | ||
12 | "strings" | ||
13 | "time" | ||
14 | |||
15 | "golang.org/x/crypto/ssh" | ||
16 | ) | ||
17 | |||
18 | // Helpers for generating random tidbits for use in identifiers to prevent | ||
19 | // collisions in acceptance tests. | ||
20 | |||
21 | // RandInt generates a random integer | ||
22 | func RandInt() int { | ||
23 | reseed() | ||
24 | return rand.New(rand.NewSource(time.Now().UnixNano())).Int() | ||
25 | } | ||
26 | |||
27 | // RandomWithPrefix is used to generate a unique name with a prefix, for | ||
28 | // randomizing names in acceptance tests | ||
29 | func RandomWithPrefix(name string) string { | ||
30 | reseed() | ||
31 | return fmt.Sprintf("%s-%d", name, rand.New(rand.NewSource(time.Now().UnixNano())).Int()) | ||
32 | } | ||
33 | |||
34 | func RandIntRange(min int, max int) int { | ||
35 | reseed() | ||
36 | source := rand.New(rand.NewSource(time.Now().UnixNano())) | ||
37 | rangeMax := max - min | ||
38 | |||
39 | return int(source.Int31n(int32(rangeMax))) | ||
40 | } | ||
41 | |||
42 | // RandString generates a random alphanumeric string of the length specified | ||
43 | func RandString(strlen int) string { | ||
44 | return RandStringFromCharSet(strlen, CharSetAlphaNum) | ||
45 | } | ||
46 | |||
47 | // RandStringFromCharSet generates a random string by selecting characters from | ||
48 | // the charset provided | ||
49 | func RandStringFromCharSet(strlen int, charSet string) string { | ||
50 | reseed() | ||
51 | result := make([]byte, strlen) | ||
52 | for i := 0; i < strlen; i++ { | ||
53 | result[i] = charSet[rand.Intn(len(charSet))] | ||
54 | } | ||
55 | return string(result) | ||
56 | } | ||
57 | |||
58 | // RandSSHKeyPair generates a public and private SSH key pair. The public key is | ||
59 | // returned in OpenSSH format, and the private key is PEM encoded. | ||
60 | func RandSSHKeyPair(comment string) (string, string, error) { | ||
61 | privateKey, err := rsa.GenerateKey(crand.Reader, 1024) | ||
62 | if err != nil { | ||
63 | return "", "", err | ||
64 | } | ||
65 | |||
66 | var privateKeyBuffer bytes.Buffer | ||
67 | privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)} | ||
68 | if err := pem.Encode(bufio.NewWriter(&privateKeyBuffer), privateKeyPEM); err != nil { | ||
69 | return "", "", err | ||
70 | } | ||
71 | |||
72 | publicKey, err := ssh.NewPublicKey(&privateKey.PublicKey) | ||
73 | if err != nil { | ||
74 | return "", "", err | ||
75 | } | ||
76 | keyMaterial := strings.TrimSpace(string(ssh.MarshalAuthorizedKey(publicKey))) | ||
77 | return fmt.Sprintf("%s %s", keyMaterial, comment), privateKeyBuffer.String(), nil | ||
78 | } | ||
79 | |||
80 | // Seeds random with current timestamp | ||
81 | func reseed() { | ||
82 | rand.Seed(time.Now().UTC().UnixNano()) | ||
83 | } | ||
84 | |||
85 | const ( | ||
86 | // CharSetAlphaNum is the alphanumeric character set for use with | ||
87 | // RandStringFromCharSet | ||
88 | CharSetAlphaNum = "abcdefghijklmnopqrstuvwxyz012346789" | ||
89 | |||
90 | // CharSetAlpha is the alphabetical character set for use with | ||
91 | // RandStringFromCharSet | ||
92 | CharSetAlpha = "abcdefghijklmnopqrstuvwxyz" | ||
93 | ) | ||
diff --git a/vendor/github.com/hashicorp/terraform/helper/acctest/remotetests.go b/vendor/github.com/hashicorp/terraform/helper/acctest/remotetests.go deleted file mode 100644 index 87c60b8..0000000 --- a/vendor/github.com/hashicorp/terraform/helper/acctest/remotetests.go +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | package acctest | ||
2 | |||
3 | import ( | ||
4 | "net/http" | ||
5 | "os" | ||
6 | "testing" | ||
7 | ) | ||
8 | |||
9 | // SkipRemoteTestsEnvVar is an environment variable that can be set by a user | ||
10 | // running the tests in an environment with limited network connectivity. By | ||
11 | // default, tests requiring internet connectivity make an effort to skip if no | ||
12 | // internet is available, but in some cases the smoke test will pass even | ||
13 | // though the test should still be skipped. | ||
14 | const SkipRemoteTestsEnvVar = "TF_SKIP_REMOTE_TESTS" | ||
15 | |||
16 | // RemoteTestPrecheck is meant to be run by any unit test that requires | ||
17 | // outbound internet connectivity. The test will be skipped if it's | ||
18 | // unavailable. | ||
19 | func RemoteTestPrecheck(t *testing.T) { | ||
20 | if os.Getenv(SkipRemoteTestsEnvVar) != "" { | ||
21 | t.Skipf("skipping test, %s was set", SkipRemoteTestsEnvVar) | ||
22 | } | ||
23 | |||
24 | if _, err := http.Get("http://google.com"); err != nil { | ||
25 | t.Skipf("skipping, internet seems to not be available: %s", err) | ||
26 | } | ||
27 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/helper/resource/testing.go b/vendor/github.com/hashicorp/terraform/helper/resource/testing.go index 04367c5..ebdbde2 100644 --- a/vendor/github.com/hashicorp/terraform/helper/resource/testing.go +++ b/vendor/github.com/hashicorp/terraform/helper/resource/testing.go | |||
@@ -1,6 +1,7 @@ | |||
1 | package resource | 1 | package resource |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "flag" | ||
4 | "fmt" | 5 | "fmt" |
5 | "io" | 6 | "io" |
6 | "io/ioutil" | 7 | "io/ioutil" |
@@ -20,6 +21,153 @@ import ( | |||
20 | "github.com/hashicorp/terraform/terraform" | 21 | "github.com/hashicorp/terraform/terraform" |
21 | ) | 22 | ) |
22 | 23 | ||
24 | // flagSweep is a flag available when running tests on the command line. It | ||
25 | // contains a comma seperated list of regions to for the sweeper functions to | ||
26 | // run in. This flag bypasses the normal Test path and instead runs functions designed to | ||
27 | // clean up any leaked resources a testing environment could have created. It is | ||
28 | // a best effort attempt, and relies on Provider authors to implement "Sweeper" | ||
29 | // methods for resources. | ||
30 | |||
31 | // Adding Sweeper methods with AddTestSweepers will | ||
32 | // construct a list of sweeper funcs to be called here. We iterate through | ||
33 | // regions provided by the sweep flag, and for each region we iterate through the | ||
34 | // tests, and exit on any errors. At time of writing, sweepers are ran | ||
35 | // sequentially, however they can list dependencies to be ran first. We track | ||
36 | // the sweepers that have been ran, so as to not run a sweeper twice for a given | ||
37 | // region. | ||
38 | // | ||
39 | // WARNING: | ||
40 | // Sweepers are designed to be destructive. You should not use the -sweep flag | ||
41 | // in any environment that is not strictly a test environment. Resources will be | ||
42 | // destroyed. | ||
43 | |||
44 | var flagSweep = flag.String("sweep", "", "List of Regions to run available Sweepers") | ||
45 | var flagSweepRun = flag.String("sweep-run", "", "Comma seperated list of Sweeper Tests to run") | ||
46 | var sweeperFuncs map[string]*Sweeper | ||
47 | |||
48 | // map of sweepers that have ran, and the success/fail status based on any error | ||
49 | // raised | ||
50 | var sweeperRunList map[string]bool | ||
51 | |||
52 | // type SweeperFunc is a signature for a function that acts as a sweeper. It | ||
53 | // accepts a string for the region that the sweeper is to be ran in. This | ||
54 | // function must be able to construct a valid client for that region. | ||
55 | type SweeperFunc func(r string) error | ||
56 | |||
57 | type Sweeper struct { | ||
58 | // Name for sweeper. Must be unique to be ran by the Sweeper Runner | ||
59 | Name string | ||
60 | |||
61 | // Dependencies list the const names of other Sweeper functions that must be ran | ||
62 | // prior to running this Sweeper. This is an ordered list that will be invoked | ||
63 | // recursively at the helper/resource level | ||
64 | Dependencies []string | ||
65 | |||
66 | // Sweeper function that when invoked sweeps the Provider of specific | ||
67 | // resources | ||
68 | F SweeperFunc | ||
69 | } | ||
70 | |||
71 | func init() { | ||
72 | sweeperFuncs = make(map[string]*Sweeper) | ||
73 | } | ||
74 | |||
75 | // AddTestSweepers function adds a given name and Sweeper configuration | ||
76 | // pair to the internal sweeperFuncs map. Invoke this function to register a | ||
77 | // resource sweeper to be available for running when the -sweep flag is used | ||
78 | // with `go test`. Sweeper names must be unique to help ensure a given sweeper | ||
79 | // is only ran once per run. | ||
80 | func AddTestSweepers(name string, s *Sweeper) { | ||
81 | if _, ok := sweeperFuncs[name]; ok { | ||
82 | log.Fatalf("[ERR] Error adding (%s) to sweeperFuncs: function already exists in map", name) | ||
83 | } | ||
84 | |||
85 | sweeperFuncs[name] = s | ||
86 | } | ||
87 | |||
88 | func TestMain(m *testing.M) { | ||
89 | flag.Parse() | ||
90 | if *flagSweep != "" { | ||
91 | // parse flagSweep contents for regions to run | ||
92 | regions := strings.Split(*flagSweep, ",") | ||
93 | |||
94 | // get filtered list of sweepers to run based on sweep-run flag | ||
95 | sweepers := filterSweepers(*flagSweepRun, sweeperFuncs) | ||
96 | for _, region := range regions { | ||
97 | region = strings.TrimSpace(region) | ||
98 | // reset sweeperRunList for each region | ||
99 | sweeperRunList = map[string]bool{} | ||
100 | |||
101 | log.Printf("[DEBUG] Running Sweepers for region (%s):\n", region) | ||
102 | for _, sweeper := range sweepers { | ||
103 | if err := runSweeperWithRegion(region, sweeper); err != nil { | ||
104 | log.Fatalf("[ERR] error running (%s): %s", sweeper.Name, err) | ||
105 | } | ||
106 | } | ||
107 | |||
108 | log.Printf("Sweeper Tests ran:\n") | ||
109 | for s, _ := range sweeperRunList { | ||
110 | fmt.Printf("\t- %s\n", s) | ||
111 | } | ||
112 | } | ||
113 | } else { | ||
114 | os.Exit(m.Run()) | ||
115 | } | ||
116 | } | ||
117 | |||
118 | // filterSweepers takes a comma seperated string listing the names of sweepers | ||
119 | // to be ran, and returns a filtered set from the list of all of sweepers to | ||
120 | // run based on the names given. | ||
121 | func filterSweepers(f string, source map[string]*Sweeper) map[string]*Sweeper { | ||
122 | filterSlice := strings.Split(strings.ToLower(f), ",") | ||
123 | if len(filterSlice) == 1 && filterSlice[0] == "" { | ||
124 | // if the filter slice is a single element of "" then no sweeper list was | ||
125 | // given, so just return the full list | ||
126 | return source | ||
127 | } | ||
128 | |||
129 | sweepers := make(map[string]*Sweeper) | ||
130 | for name, sweeper := range source { | ||
131 | for _, s := range filterSlice { | ||
132 | if strings.Contains(strings.ToLower(name), s) { | ||
133 | sweepers[name] = sweeper | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | return sweepers | ||
138 | } | ||
139 | |||
140 | // runSweeperWithRegion recieves a sweeper and a region, and recursively calls | ||
141 | // itself with that region for every dependency found for that sweeper. If there | ||
142 | // are no dependencies, invoke the contained sweeper fun with the region, and | ||
143 | // add the success/fail status to the sweeperRunList. | ||
144 | func runSweeperWithRegion(region string, s *Sweeper) error { | ||
145 | for _, dep := range s.Dependencies { | ||
146 | if depSweeper, ok := sweeperFuncs[dep]; ok { | ||
147 | log.Printf("[DEBUG] Sweeper (%s) has dependency (%s), running..", s.Name, dep) | ||
148 | if err := runSweeperWithRegion(region, depSweeper); err != nil { | ||
149 | return err | ||
150 | } | ||
151 | } else { | ||
152 | log.Printf("[DEBUG] Sweeper (%s) has dependency (%s), but that sweeper was not found", s.Name, dep) | ||
153 | } | ||
154 | } | ||
155 | |||
156 | if _, ok := sweeperRunList[s.Name]; ok { | ||
157 | log.Printf("[DEBUG] Sweeper (%s) already ran in region (%s)", s.Name, region) | ||
158 | return nil | ||
159 | } | ||
160 | |||
161 | runE := s.F(region) | ||
162 | if runE == nil { | ||
163 | sweeperRunList[s.Name] = true | ||
164 | } else { | ||
165 | sweeperRunList[s.Name] = false | ||
166 | } | ||
167 | |||
168 | return runE | ||
169 | } | ||
170 | |||
23 | const TestEnvVar = "TF_ACC" | 171 | const TestEnvVar = "TF_ACC" |
24 | 172 | ||
25 | // TestProvider can be implemented by any ResourceProvider to provide custom | 173 | // TestProvider can be implemented by any ResourceProvider to provide custom |
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go b/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go index c1564a2..856c675 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go | |||
@@ -41,6 +41,10 @@ type Provisioner struct { | |||
41 | // information. | 41 | // information. |
42 | ApplyFunc func(ctx context.Context) error | 42 | ApplyFunc func(ctx context.Context) error |
43 | 43 | ||
44 | // ValidateFunc is a function for extended validation. This is optional | ||
45 | // and should be used when individual field validation is not enough. | ||
46 | ValidateFunc func(*ResourceData) ([]string, []error) | ||
47 | |||
44 | stopCtx context.Context | 48 | stopCtx context.Context |
45 | stopCtxCancel context.CancelFunc | 49 | stopCtxCancel context.CancelFunc |
46 | stopOnce sync.Once | 50 | stopOnce sync.Once |
@@ -117,8 +121,30 @@ func (p *Provisioner) Stop() error { | |||
117 | return nil | 121 | return nil |
118 | } | 122 | } |
119 | 123 | ||
120 | func (p *Provisioner) Validate(c *terraform.ResourceConfig) ([]string, []error) { | 124 | func (p *Provisioner) Validate(config *terraform.ResourceConfig) ([]string, []error) { |
121 | return schemaMap(p.Schema).Validate(c) | 125 | if err := p.InternalValidate(); err != nil { |
126 | return nil, []error{fmt.Errorf( | ||
127 | "Internal validation of the provisioner failed! This is always a bug\n"+ | ||
128 | "with the provisioner itself, and not a user issue. Please report\n"+ | ||
129 | "this bug:\n\n%s", err)} | ||
130 | } | ||
131 | w := []string{} | ||
132 | e := []error{} | ||
133 | if p.Schema != nil { | ||
134 | w2, e2 := schemaMap(p.Schema).Validate(config) | ||
135 | w = append(w, w2...) | ||
136 | e = append(e, e2...) | ||
137 | } | ||
138 | if p.ValidateFunc != nil { | ||
139 | data := &ResourceData{ | ||
140 | schema: p.Schema, | ||
141 | config: config, | ||
142 | } | ||
143 | w2, e2 := p.ValidateFunc(data) | ||
144 | w = append(w, w2...) | ||
145 | e = append(e, e2...) | ||
146 | } | ||
147 | return w, e | ||
122 | } | 148 | } |
123 | 149 | ||
124 | // Apply implementation of terraform.ResourceProvisioner interface. | 150 | // Apply implementation of terraform.ResourceProvisioner interface. |
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/schema.go b/vendor/github.com/hashicorp/terraform/helper/schema/schema.go index 32d1721..632672a 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/schema.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/schema.go | |||
@@ -1373,8 +1373,8 @@ func (m schemaMap) validateObject( | |||
1373 | k string, | 1373 | k string, |
1374 | schema map[string]*Schema, | 1374 | schema map[string]*Schema, |
1375 | c *terraform.ResourceConfig) ([]string, []error) { | 1375 | c *terraform.ResourceConfig) ([]string, []error) { |
1376 | raw, _ := c.GetRaw(k) | 1376 | raw, _ := c.Get(k) |
1377 | if _, ok := raw.(map[string]interface{}); !ok { | 1377 | if _, ok := raw.(map[string]interface{}); !ok && !c.IsComputed(k) { |
1378 | return nil, []error{fmt.Errorf( | 1378 | return nil, []error{fmt.Errorf( |
1379 | "%s: expected object, got %s", | 1379 | "%s: expected object, got %s", |
1380 | k, reflect.ValueOf(raw).Kind())} | 1380 | k, reflect.ValueOf(raw).Kind())} |
diff --git a/vendor/github.com/hashicorp/terraform/helper/structure/expand_json.go b/vendor/github.com/hashicorp/terraform/helper/structure/expand_json.go deleted file mode 100644 index b3eb90f..0000000 --- a/vendor/github.com/hashicorp/terraform/helper/structure/expand_json.go +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | package structure | ||
2 | |||
3 | import "encoding/json" | ||
4 | |||
5 | func ExpandJsonFromString(jsonString string) (map[string]interface{}, error) { | ||
6 | var result map[string]interface{} | ||
7 | |||
8 | err := json.Unmarshal([]byte(jsonString), &result) | ||
9 | |||
10 | return result, err | ||
11 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/helper/structure/flatten_json.go b/vendor/github.com/hashicorp/terraform/helper/structure/flatten_json.go deleted file mode 100644 index 578ad2e..0000000 --- a/vendor/github.com/hashicorp/terraform/helper/structure/flatten_json.go +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | package structure | ||
2 | |||
3 | import "encoding/json" | ||
4 | |||
5 | func FlattenJsonToString(input map[string]interface{}) (string, error) { | ||
6 | if len(input) == 0 { | ||
7 | return "", nil | ||
8 | } | ||
9 | |||
10 | result, err := json.Marshal(input) | ||
11 | if err != nil { | ||
12 | return "", err | ||
13 | } | ||
14 | |||
15 | return string(result), nil | ||
16 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/helper/structure/normalize_json.go b/vendor/github.com/hashicorp/terraform/helper/structure/normalize_json.go deleted file mode 100644 index 3256b47..0000000 --- a/vendor/github.com/hashicorp/terraform/helper/structure/normalize_json.go +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | package structure | ||
2 | |||
3 | import "encoding/json" | ||
4 | |||
5 | // Takes a value containing JSON string and passes it through | ||
6 | // the JSON parser to normalize it, returns either a parsing | ||
7 | // error or normalized JSON string. | ||
8 | func NormalizeJsonString(jsonString interface{}) (string, error) { | ||
9 | var j interface{} | ||
10 | |||
11 | if jsonString == nil || jsonString.(string) == "" { | ||
12 | return "", nil | ||
13 | } | ||
14 | |||
15 | s := jsonString.(string) | ||
16 | |||
17 | err := json.Unmarshal([]byte(s), &j) | ||
18 | if err != nil { | ||
19 | return s, err | ||
20 | } | ||
21 | |||
22 | bytes, _ := json.Marshal(j) | ||
23 | return string(bytes[:]), nil | ||
24 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/helper/structure/suppress_json_diff.go b/vendor/github.com/hashicorp/terraform/helper/structure/suppress_json_diff.go deleted file mode 100644 index 46f794a..0000000 --- a/vendor/github.com/hashicorp/terraform/helper/structure/suppress_json_diff.go +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | package structure | ||
2 | |||
3 | import ( | ||
4 | "reflect" | ||
5 | |||
6 | "github.com/hashicorp/terraform/helper/schema" | ||
7 | ) | ||
8 | |||
9 | func SuppressJsonDiff(k, old, new string, d *schema.ResourceData) bool { | ||
10 | oldMap, err := ExpandJsonFromString(old) | ||
11 | if err != nil { | ||
12 | return false | ||
13 | } | ||
14 | |||
15 | newMap, err := ExpandJsonFromString(new) | ||
16 | if err != nil { | ||
17 | return false | ||
18 | } | ||
19 | |||
20 | return reflect.DeepEqual(oldMap, newMap) | ||
21 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/helper/validation/validation.go b/vendor/github.com/hashicorp/terraform/helper/validation/validation.go deleted file mode 100644 index 7b894f5..0000000 --- a/vendor/github.com/hashicorp/terraform/helper/validation/validation.go +++ /dev/null | |||
@@ -1,108 +0,0 @@ | |||
1 | package validation | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "net" | ||
6 | "strings" | ||
7 | |||
8 | "github.com/hashicorp/terraform/helper/schema" | ||
9 | "github.com/hashicorp/terraform/helper/structure" | ||
10 | ) | ||
11 | |||
12 | // IntBetween returns a SchemaValidateFunc which tests if the provided value | ||
13 | // is of type int and is between min and max (inclusive) | ||
14 | func IntBetween(min, max int) schema.SchemaValidateFunc { | ||
15 | return func(i interface{}, k string) (s []string, es []error) { | ||
16 | v, ok := i.(int) | ||
17 | if !ok { | ||
18 | es = append(es, fmt.Errorf("expected type of %s to be int", k)) | ||
19 | return | ||
20 | } | ||
21 | |||
22 | if v < min || v > max { | ||
23 | es = append(es, fmt.Errorf("expected %s to be in the range (%d - %d), got %d", k, min, max, v)) | ||
24 | return | ||
25 | } | ||
26 | |||
27 | return | ||
28 | } | ||
29 | } | ||
30 | |||
31 | // StringInSlice returns a SchemaValidateFunc which tests if the provided value | ||
32 | // is of type string and matches the value of an element in the valid slice | ||
33 | // will test with in lower case if ignoreCase is true | ||
34 | func StringInSlice(valid []string, ignoreCase bool) schema.SchemaValidateFunc { | ||
35 | return func(i interface{}, k string) (s []string, es []error) { | ||
36 | v, ok := i.(string) | ||
37 | if !ok { | ||
38 | es = append(es, fmt.Errorf("expected type of %s to be string", k)) | ||
39 | return | ||
40 | } | ||
41 | |||
42 | for _, str := range valid { | ||
43 | if v == str || (ignoreCase && strings.ToLower(v) == strings.ToLower(str)) { | ||
44 | return | ||
45 | } | ||
46 | } | ||
47 | |||
48 | es = append(es, fmt.Errorf("expected %s to be one of %v, got %s", k, valid, v)) | ||
49 | return | ||
50 | } | ||
51 | } | ||
52 | |||
53 | // StringLenBetween returns a SchemaValidateFunc which tests if the provided value | ||
54 | // is of type string and has length between min and max (inclusive) | ||
55 | func StringLenBetween(min, max int) schema.SchemaValidateFunc { | ||
56 | return func(i interface{}, k string) (s []string, es []error) { | ||
57 | v, ok := i.(string) | ||
58 | if !ok { | ||
59 | es = append(es, fmt.Errorf("expected type of %s to be string", k)) | ||
60 | return | ||
61 | } | ||
62 | if len(v) < min || len(v) > max { | ||
63 | es = append(es, fmt.Errorf("expected length of %s to be in the range (%d - %d), got %s", k, min, max, v)) | ||
64 | } | ||
65 | return | ||
66 | } | ||
67 | } | ||
68 | |||
69 | // CIDRNetwork returns a SchemaValidateFunc which tests if the provided value | ||
70 | // is of type string, is in valid CIDR network notation, and has significant bits between min and max (inclusive) | ||
71 | func CIDRNetwork(min, max int) schema.SchemaValidateFunc { | ||
72 | return func(i interface{}, k string) (s []string, es []error) { | ||
73 | v, ok := i.(string) | ||
74 | if !ok { | ||
75 | es = append(es, fmt.Errorf("expected type of %s to be string", k)) | ||
76 | return | ||
77 | } | ||
78 | |||
79 | _, ipnet, err := net.ParseCIDR(v) | ||
80 | if err != nil { | ||
81 | es = append(es, fmt.Errorf( | ||
82 | "expected %s to contain a valid CIDR, got: %s with err: %s", k, v, err)) | ||
83 | return | ||
84 | } | ||
85 | |||
86 | if ipnet == nil || v != ipnet.String() { | ||
87 | es = append(es, fmt.Errorf( | ||
88 | "expected %s to contain a valid network CIDR, expected %s, got %s", | ||
89 | k, ipnet, v)) | ||
90 | } | ||
91 | |||
92 | sigbits, _ := ipnet.Mask.Size() | ||
93 | if sigbits < min || sigbits > max { | ||
94 | es = append(es, fmt.Errorf( | ||
95 | "expected %q to contain a network CIDR with between %d and %d significant bits, got: %d", | ||
96 | k, min, max, sigbits)) | ||
97 | } | ||
98 | |||
99 | return | ||
100 | } | ||
101 | } | ||
102 | |||
103 | func ValidateJsonString(v interface{}, k string) (ws []string, errors []error) { | ||
104 | if _, err := structure.NormalizeJsonString(v); err != nil { | ||
105 | errors = append(errors, fmt.Errorf("%q contains an invalid JSON: %s", k, err)) | ||
106 | } | ||
107 | return | ||
108 | } | ||