aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com
diff options
context:
space:
mode:
authorRadek Simko <radek.simko@gmail.com>2017-08-10 14:38:14 +0200
committerRadek Simko <radek.simko@gmail.com>2017-08-10 14:38:14 +0200
commitc680a8e1622ed0f18751d9d167c836ee24f5e897 (patch)
tree864f925049d422033dd25a73bafce32b361c8827 /vendor/github.com
parent38f8880ac81bfabc6d7f82e4dc89661f20fc559e (diff)
downloadterraform-provider-statuscake-c680a8e1622ed0f18751d9d167c836ee24f5e897.tar.gz
terraform-provider-statuscake-c680a8e1622ed0f18751d9d167c836ee24f5e897.tar.zst
terraform-provider-statuscake-c680a8e1622ed0f18751d9d167c836ee24f5e897.zip
vendor: github.com/hashicorp/terraform/...@v0.10.0
Diffstat (limited to 'vendor/github.com')
-rw-r--r--vendor/github.com/blang/semver/LICENSE22
-rw-r--r--vendor/github.com/blang/semver/README.md194
-rw-r--r--vendor/github.com/blang/semver/json.go23
-rw-r--r--vendor/github.com/blang/semver/package.json17
-rw-r--r--vendor/github.com/blang/semver/range.go416
-rw-r--r--vendor/github.com/blang/semver/semver.go418
-rw-r--r--vendor/github.com/blang/semver/sort.go28
-rw-r--r--vendor/github.com/blang/semver/sql.go30
-rw-r--r--vendor/github.com/hashicorp/go-cleanhttp/LICENSE363
-rw-r--r--vendor/github.com/hashicorp/go-cleanhttp/README.md30
-rw-r--r--vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go56
-rw-r--r--vendor/github.com/hashicorp/go-cleanhttp/doc.go20
-rw-r--r--vendor/github.com/hashicorp/terraform/config/config.go42
-rw-r--r--vendor/github.com/hashicorp/terraform/config/interpolate_funcs.go17
-rw-r--r--vendor/github.com/hashicorp/terraform/config/loader.go6
-rw-r--r--vendor/github.com/hashicorp/terraform/config/loader_hcl.go28
-rw-r--r--vendor/github.com/hashicorp/terraform/config/module/tree.go19
-rw-r--r--vendor/github.com/hashicorp/terraform/config/providers.go103
-rw-r--r--vendor/github.com/hashicorp/terraform/flatmap/expand.go7
-rw-r--r--vendor/github.com/hashicorp/terraform/helper/resource/id.go33
-rw-r--r--vendor/github.com/hashicorp/terraform/helper/resource/testing.go44
-rw-r--r--vendor/github.com/hashicorp/terraform/helper/schema/provider.go17
-rw-r--r--vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go52
-rw-r--r--vendor/github.com/hashicorp/terraform/helper/schema/resource.go23
-rw-r--r--vendor/github.com/hashicorp/terraform/helper/schema/schema.go14
-rw-r--r--vendor/github.com/hashicorp/terraform/helper/shadow/closer.go21
-rw-r--r--vendor/github.com/hashicorp/terraform/helper/shadow/value.go8
-rw-r--r--vendor/github.com/hashicorp/terraform/moduledeps/dependencies.go43
-rw-r--r--vendor/github.com/hashicorp/terraform/moduledeps/doc.go7
-rw-r--r--vendor/github.com/hashicorp/terraform/moduledeps/module.go204
-rw-r--r--vendor/github.com/hashicorp/terraform/moduledeps/provider.go30
-rw-r--r--vendor/github.com/hashicorp/terraform/plugin/client.go24
-rw-r--r--vendor/github.com/hashicorp/terraform/plugin/discovery/error.go30
-rw-r--r--vendor/github.com/hashicorp/terraform/plugin/discovery/find.go168
-rw-r--r--vendor/github.com/hashicorp/terraform/plugin/discovery/get.go424
-rw-r--r--vendor/github.com/hashicorp/terraform/plugin/discovery/meta.go41
-rw-r--r--vendor/github.com/hashicorp/terraform/plugin/discovery/meta_set.go195
-rw-r--r--vendor/github.com/hashicorp/terraform/plugin/discovery/requirements.go105
-rw-r--r--vendor/github.com/hashicorp/terraform/plugin/discovery/signature.go53
-rw-r--r--vendor/github.com/hashicorp/terraform/plugin/discovery/version.go72
-rw-r--r--vendor/github.com/hashicorp/terraform/plugin/discovery/version_set.go84
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/context.go32
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/diff.go6
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/eval_diff.go36
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go10
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/graph_builder_refresh.go10
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/interpolate.go8
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/module_dependencies.go156
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/node_resource_refresh.go95
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/plan.go51
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/resource_address.go176
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/resource_provider.go81
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/state.go66
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/test_failure9
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/transform_resource_refresh_plannable.go55
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/transform_targets.go13
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/util.go20
-rw-r--r--vendor/github.com/hashicorp/terraform/terraform/version.go4
58 files changed, 4155 insertions, 204 deletions
diff --git a/vendor/github.com/blang/semver/LICENSE b/vendor/github.com/blang/semver/LICENSE
new file mode 100644
index 0000000..5ba5c86
--- /dev/null
+++ b/vendor/github.com/blang/semver/LICENSE
@@ -0,0 +1,22 @@
1The MIT License
2
3Copyright (c) 2014 Benedikt Lang <github at benediktlang.de>
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
22
diff --git a/vendor/github.com/blang/semver/README.md b/vendor/github.com/blang/semver/README.md
new file mode 100644
index 0000000..08b2e4a
--- /dev/null
+++ b/vendor/github.com/blang/semver/README.md
@@ -0,0 +1,194 @@
1semver for golang [![Build Status](https://travis-ci.org/blang/semver.svg?branch=master)](https://travis-ci.org/blang/semver) [![GoDoc](https://godoc.org/github.com/blang/semver?status.png)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master)
2======
3
4semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`.
5
6Usage
7-----
8```bash
9$ go get github.com/blang/semver
10```
11Note: Always vendor your dependencies or fix on a specific version tag.
12
13```go
14import github.com/blang/semver
15v1, err := semver.Make("1.0.0-beta")
16v2, err := semver.Make("2.0.0-beta")
17v1.Compare(v2)
18```
19
20Also check the [GoDocs](http://godoc.org/github.com/blang/semver).
21
22Why should I use this lib?
23-----
24
25- Fully spec compatible
26- No reflection
27- No regex
28- Fully tested (Coverage >99%)
29- Readable parsing/validation errors
30- Fast (See [Benchmarks](#benchmarks))
31- Only Stdlib
32- Uses values instead of pointers
33- Many features, see below
34
35
36Features
37-----
38
39- Parsing and validation at all levels
40- Comparator-like comparisons
41- Compare Helper Methods
42- InPlace manipulation
43- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1`
44- Wildcards `>=1.x`, `<=2.5.x`
45- Sortable (implements sort.Interface)
46- database/sql compatible (sql.Scanner/Valuer)
47- encoding/json compatible (json.Marshaler/Unmarshaler)
48
49Ranges
50------
51
52A `Range` is a set of conditions which specify which versions satisfy the range.
53
54A condition is composed of an operator and a version. The supported operators are:
55
56- `<1.0.0` Less than `1.0.0`
57- `<=1.0.0` Less than or equal to `1.0.0`
58- `>1.0.0` Greater than `1.0.0`
59- `>=1.0.0` Greater than or equal to `1.0.0`
60- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0`
61- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`.
62
63Note that spaces between the operator and the version will be gracefully tolerated.
64
65A `Range` can link multiple `Ranges` separated by space:
66
67Ranges can be linked by logical AND:
68
69 - `>1.0.0 <2.0.0` would match between both ranges, so `1.1.1` and `1.8.7` but not `1.0.0` or `2.0.0`
70 - `>1.0.0 <3.0.0 !2.0.3-beta.2` would match every version between `1.0.0` and `3.0.0` except `2.0.3-beta.2`
71
72Ranges can also be linked by logical OR:
73
74 - `<2.0.0 || >=3.0.0` would match `1.x.x` and `3.x.x` but not `2.x.x`
75
76AND has a higher precedence than OR. It's not possible to use brackets.
77
78Ranges can be combined by both AND and OR
79
80 - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
81
82Range usage:
83
84```
85v, err := semver.Parse("1.2.3")
86range, err := semver.ParseRange(">1.0.0 <2.0.0 || >=3.0.0")
87if range(v) {
88 //valid
89}
90
91```
92
93Example
94-----
95
96Have a look at full examples in [examples/main.go](examples/main.go)
97
98```go
99import github.com/blang/semver
100
101v, err := semver.Make("0.0.1-alpha.preview+123.github")
102fmt.Printf("Major: %d\n", v.Major)
103fmt.Printf("Minor: %d\n", v.Minor)
104fmt.Printf("Patch: %d\n", v.Patch)
105fmt.Printf("Pre: %s\n", v.Pre)
106fmt.Printf("Build: %s\n", v.Build)
107
108// Prerelease versions array
109if len(v.Pre) > 0 {
110 fmt.Println("Prerelease versions:")
111 for i, pre := range v.Pre {
112 fmt.Printf("%d: %q\n", i, pre)
113 }
114}
115
116// Build meta data array
117if len(v.Build) > 0 {
118 fmt.Println("Build meta data:")
119 for i, build := range v.Build {
120 fmt.Printf("%d: %q\n", i, build)
121 }
122}
123
124v001, err := semver.Make("0.0.1")
125// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE
126v001.GT(v) == true
127v.LT(v001) == true
128v.GTE(v) == true
129v.LTE(v) == true
130
131// Or use v.Compare(v2) for comparisons (-1, 0, 1):
132v001.Compare(v) == 1
133v.Compare(v001) == -1
134v.Compare(v) == 0
135
136// Manipulate Version in place:
137v.Pre[0], err = semver.NewPRVersion("beta")
138if err != nil {
139 fmt.Printf("Error parsing pre release version: %q", err)
140}
141
142fmt.Println("\nValidate versions:")
143v.Build[0] = "?"
144
145err = v.Validate()
146if err != nil {
147 fmt.Printf("Validation failed: %s\n", err)
148}
149```
150
151
152Benchmarks
153-----
154
155 BenchmarkParseSimple-4 5000000 390 ns/op 48 B/op 1 allocs/op
156 BenchmarkParseComplex-4 1000000 1813 ns/op 256 B/op 7 allocs/op
157 BenchmarkParseAverage-4 1000000 1171 ns/op 163 B/op 4 allocs/op
158 BenchmarkStringSimple-4 20000000 119 ns/op 16 B/op 1 allocs/op
159 BenchmarkStringLarger-4 10000000 206 ns/op 32 B/op 2 allocs/op
160 BenchmarkStringComplex-4 5000000 324 ns/op 80 B/op 3 allocs/op
161 BenchmarkStringAverage-4 5000000 273 ns/op 53 B/op 2 allocs/op
162 BenchmarkValidateSimple-4 200000000 9.33 ns/op 0 B/op 0 allocs/op
163 BenchmarkValidateComplex-4 3000000 469 ns/op 0 B/op 0 allocs/op
164 BenchmarkValidateAverage-4 5000000 256 ns/op 0 B/op 0 allocs/op
165 BenchmarkCompareSimple-4 100000000 11.8 ns/op 0 B/op 0 allocs/op
166 BenchmarkCompareComplex-4 50000000 30.8 ns/op 0 B/op 0 allocs/op
167 BenchmarkCompareAverage-4 30000000 41.5 ns/op 0 B/op 0 allocs/op
168 BenchmarkSort-4 3000000 419 ns/op 256 B/op 2 allocs/op
169 BenchmarkRangeParseSimple-4 2000000 850 ns/op 192 B/op 5 allocs/op
170 BenchmarkRangeParseAverage-4 1000000 1677 ns/op 400 B/op 10 allocs/op
171 BenchmarkRangeParseComplex-4 300000 5214 ns/op 1440 B/op 30 allocs/op
172 BenchmarkRangeMatchSimple-4 50000000 25.6 ns/op 0 B/op 0 allocs/op
173 BenchmarkRangeMatchAverage-4 30000000 56.4 ns/op 0 B/op 0 allocs/op
174 BenchmarkRangeMatchComplex-4 10000000 153 ns/op 0 B/op 0 allocs/op
175
176See benchmark cases at [semver_test.go](semver_test.go)
177
178
179Motivation
180-----
181
182I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like.
183
184
185Contribution
186-----
187
188Feel free to make a pull request. For bigger changes create a issue first to discuss about it.
189
190
191License
192-----
193
194See [LICENSE](LICENSE) file.
diff --git a/vendor/github.com/blang/semver/json.go b/vendor/github.com/blang/semver/json.go
new file mode 100644
index 0000000..a74bf7c
--- /dev/null
+++ b/vendor/github.com/blang/semver/json.go
@@ -0,0 +1,23 @@
1package semver
2
3import (
4 "encoding/json"
5)
6
7// MarshalJSON implements the encoding/json.Marshaler interface.
8func (v Version) MarshalJSON() ([]byte, error) {
9 return json.Marshal(v.String())
10}
11
12// UnmarshalJSON implements the encoding/json.Unmarshaler interface.
13func (v *Version) UnmarshalJSON(data []byte) (err error) {
14 var versionString string
15
16 if err = json.Unmarshal(data, &versionString); err != nil {
17 return
18 }
19
20 *v, err = Parse(versionString)
21
22 return
23}
diff --git a/vendor/github.com/blang/semver/package.json b/vendor/github.com/blang/semver/package.json
new file mode 100644
index 0000000..1cf8ebd
--- /dev/null
+++ b/vendor/github.com/blang/semver/package.json
@@ -0,0 +1,17 @@
1{
2 "author": "blang",
3 "bugs": {
4 "URL": "https://github.com/blang/semver/issues",
5 "url": "https://github.com/blang/semver/issues"
6 },
7 "gx": {
8 "dvcsimport": "github.com/blang/semver"
9 },
10 "gxVersion": "0.10.0",
11 "language": "go",
12 "license": "MIT",
13 "name": "semver",
14 "releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
15 "version": "3.5.1"
16}
17
diff --git a/vendor/github.com/blang/semver/range.go b/vendor/github.com/blang/semver/range.go
new file mode 100644
index 0000000..fca406d
--- /dev/null
+++ b/vendor/github.com/blang/semver/range.go
@@ -0,0 +1,416 @@
1package semver
2
3import (
4 "fmt"
5 "strconv"
6 "strings"
7 "unicode"
8)
9
10type wildcardType int
11
12const (
13 noneWildcard wildcardType = iota
14 majorWildcard wildcardType = 1
15 minorWildcard wildcardType = 2
16 patchWildcard wildcardType = 3
17)
18
19func wildcardTypefromInt(i int) wildcardType {
20 switch i {
21 case 1:
22 return majorWildcard
23 case 2:
24 return minorWildcard
25 case 3:
26 return patchWildcard
27 default:
28 return noneWildcard
29 }
30}
31
32type comparator func(Version, Version) bool
33
34var (
35 compEQ comparator = func(v1 Version, v2 Version) bool {
36 return v1.Compare(v2) == 0
37 }
38 compNE = func(v1 Version, v2 Version) bool {
39 return v1.Compare(v2) != 0
40 }
41 compGT = func(v1 Version, v2 Version) bool {
42 return v1.Compare(v2) == 1
43 }
44 compGE = func(v1 Version, v2 Version) bool {
45 return v1.Compare(v2) >= 0
46 }
47 compLT = func(v1 Version, v2 Version) bool {
48 return v1.Compare(v2) == -1
49 }
50 compLE = func(v1 Version, v2 Version) bool {
51 return v1.Compare(v2) <= 0
52 }
53)
54
55type versionRange struct {
56 v Version
57 c comparator
58}
59
60// rangeFunc creates a Range from the given versionRange.
61func (vr *versionRange) rangeFunc() Range {
62 return Range(func(v Version) bool {
63 return vr.c(v, vr.v)
64 })
65}
66
67// Range represents a range of versions.
68// A Range can be used to check if a Version satisfies it:
69//
70// range, err := semver.ParseRange(">1.0.0 <2.0.0")
71// range(semver.MustParse("1.1.1") // returns true
72type Range func(Version) bool
73
74// OR combines the existing Range with another Range using logical OR.
75func (rf Range) OR(f Range) Range {
76 return Range(func(v Version) bool {
77 return rf(v) || f(v)
78 })
79}
80
81// AND combines the existing Range with another Range using logical AND.
82func (rf Range) AND(f Range) Range {
83 return Range(func(v Version) bool {
84 return rf(v) && f(v)
85 })
86}
87
88// ParseRange parses a range and returns a Range.
89// If the range could not be parsed an error is returned.
90//
91// Valid ranges are:
92// - "<1.0.0"
93// - "<=1.0.0"
94// - ">1.0.0"
95// - ">=1.0.0"
96// - "1.0.0", "=1.0.0", "==1.0.0"
97// - "!1.0.0", "!=1.0.0"
98//
99// A Range can consist of multiple ranges separated by space:
100// Ranges can be linked by logical AND:
101// - ">1.0.0 <2.0.0" would match between both ranges, so "1.1.1" and "1.8.7" but not "1.0.0" or "2.0.0"
102// - ">1.0.0 <3.0.0 !2.0.3-beta.2" would match every version between 1.0.0 and 3.0.0 except 2.0.3-beta.2
103//
104// Ranges can also be linked by logical OR:
105// - "<2.0.0 || >=3.0.0" would match "1.x.x" and "3.x.x" but not "2.x.x"
106//
107// AND has a higher precedence than OR. It's not possible to use brackets.
108//
109// Ranges can be combined by both AND and OR
110//
111// - `>1.0.0 <2.0.0 || >3.0.0 !4.2.1` would match `1.2.3`, `1.9.9`, `3.1.1`, but not `4.2.1`, `2.1.1`
112func ParseRange(s string) (Range, error) {
113 parts := splitAndTrim(s)
114 orParts, err := splitORParts(parts)
115 if err != nil {
116 return nil, err
117 }
118 expandedParts, err := expandWildcardVersion(orParts)
119 if err != nil {
120 return nil, err
121 }
122 var orFn Range
123 for _, p := range expandedParts {
124 var andFn Range
125 for _, ap := range p {
126 opStr, vStr, err := splitComparatorVersion(ap)
127 if err != nil {
128 return nil, err
129 }
130 vr, err := buildVersionRange(opStr, vStr)
131 if err != nil {
132 return nil, fmt.Errorf("Could not parse Range %q: %s", ap, err)
133 }
134 rf := vr.rangeFunc()
135
136 // Set function
137 if andFn == nil {
138 andFn = rf
139 } else { // Combine with existing function
140 andFn = andFn.AND(rf)
141 }
142 }
143 if orFn == nil {
144 orFn = andFn
145 } else {
146 orFn = orFn.OR(andFn)
147 }
148
149 }
150 return orFn, nil
151}
152
153// splitORParts splits the already cleaned parts by '||'.
154// Checks for invalid positions of the operator and returns an
155// error if found.
156func splitORParts(parts []string) ([][]string, error) {
157 var ORparts [][]string
158 last := 0
159 for i, p := range parts {
160 if p == "||" {
161 if i == 0 {
162 return nil, fmt.Errorf("First element in range is '||'")
163 }
164 ORparts = append(ORparts, parts[last:i])
165 last = i + 1
166 }
167 }
168 if last == len(parts) {
169 return nil, fmt.Errorf("Last element in range is '||'")
170 }
171 ORparts = append(ORparts, parts[last:])
172 return ORparts, nil
173}
174
175// buildVersionRange takes a slice of 2: operator and version
176// and builds a versionRange, otherwise an error.
177func buildVersionRange(opStr, vStr string) (*versionRange, error) {
178 c := parseComparator(opStr)
179 if c == nil {
180 return nil, fmt.Errorf("Could not parse comparator %q in %q", opStr, strings.Join([]string{opStr, vStr}, ""))
181 }
182 v, err := Parse(vStr)
183 if err != nil {
184 return nil, fmt.Errorf("Could not parse version %q in %q: %s", vStr, strings.Join([]string{opStr, vStr}, ""), err)
185 }
186
187 return &versionRange{
188 v: v,
189 c: c,
190 }, nil
191
192}
193
194// inArray checks if a byte is contained in an array of bytes
195func inArray(s byte, list []byte) bool {
196 for _, el := range list {
197 if el == s {
198 return true
199 }
200 }
201 return false
202}
203
204// splitAndTrim splits a range string by spaces and cleans whitespaces
205func splitAndTrim(s string) (result []string) {
206 last := 0
207 var lastChar byte
208 excludeFromSplit := []byte{'>', '<', '='}
209 for i := 0; i < len(s); i++ {
210 if s[i] == ' ' && !inArray(lastChar, excludeFromSplit) {
211 if last < i-1 {
212 result = append(result, s[last:i])
213 }
214 last = i + 1
215 } else if s[i] != ' ' {
216 lastChar = s[i]
217 }
218 }
219 if last < len(s)-1 {
220 result = append(result, s[last:])
221 }
222
223 for i, v := range result {
224 result[i] = strings.Replace(v, " ", "", -1)
225 }
226
227 // parts := strings.Split(s, " ")
228 // for _, x := range parts {
229 // if s := strings.TrimSpace(x); len(s) != 0 {
230 // result = append(result, s)
231 // }
232 // }
233 return
234}
235
236// splitComparatorVersion splits the comparator from the version.
237// Input must be free of leading or trailing spaces.
238func splitComparatorVersion(s string) (string, string, error) {
239 i := strings.IndexFunc(s, unicode.IsDigit)
240 if i == -1 {
241 return "", "", fmt.Errorf("Could not get version from string: %q", s)
242 }
243 return strings.TrimSpace(s[0:i]), s[i:], nil
244}
245
246// getWildcardType will return the type of wildcard that the
247// passed version contains
248func getWildcardType(vStr string) wildcardType {
249 parts := strings.Split(vStr, ".")
250 nparts := len(parts)
251 wildcard := parts[nparts-1]
252
253 possibleWildcardType := wildcardTypefromInt(nparts)
254 if wildcard == "x" {
255 return possibleWildcardType
256 }
257
258 return noneWildcard
259}
260
261// createVersionFromWildcard will convert a wildcard version
262// into a regular version, replacing 'x's with '0's, handling
263// special cases like '1.x.x' and '1.x'
264func createVersionFromWildcard(vStr string) string {
265 // handle 1.x.x
266 vStr2 := strings.Replace(vStr, ".x.x", ".x", 1)
267 vStr2 = strings.Replace(vStr2, ".x", ".0", 1)
268 parts := strings.Split(vStr2, ".")
269
270 // handle 1.x
271 if len(parts) == 2 {
272 return vStr2 + ".0"
273 }
274
275 return vStr2
276}
277
278// incrementMajorVersion will increment the major version
279// of the passed version
280func incrementMajorVersion(vStr string) (string, error) {
281 parts := strings.Split(vStr, ".")
282 i, err := strconv.Atoi(parts[0])
283 if err != nil {
284 return "", err
285 }
286 parts[0] = strconv.Itoa(i + 1)
287
288 return strings.Join(parts, "."), nil
289}
290
291// incrementMajorVersion will increment the minor version
292// of the passed version
293func incrementMinorVersion(vStr string) (string, error) {
294 parts := strings.Split(vStr, ".")
295 i, err := strconv.Atoi(parts[1])
296 if err != nil {
297 return "", err
298 }
299 parts[1] = strconv.Itoa(i + 1)
300
301 return strings.Join(parts, "."), nil
302}
303
304// expandWildcardVersion will expand wildcards inside versions
305// following these rules:
306//
307// * when dealing with patch wildcards:
308// >= 1.2.x will become >= 1.2.0
309// <= 1.2.x will become < 1.3.0
310// > 1.2.x will become >= 1.3.0
311// < 1.2.x will become < 1.2.0
312// != 1.2.x will become < 1.2.0 >= 1.3.0
313//
314// * when dealing with minor wildcards:
315// >= 1.x will become >= 1.0.0
316// <= 1.x will become < 2.0.0
317// > 1.x will become >= 2.0.0
318// < 1.0 will become < 1.0.0
319// != 1.x will become < 1.0.0 >= 2.0.0
320//
321// * when dealing with wildcards without
322// version operator:
323// 1.2.x will become >= 1.2.0 < 1.3.0
324// 1.x will become >= 1.0.0 < 2.0.0
325func expandWildcardVersion(parts [][]string) ([][]string, error) {
326 var expandedParts [][]string
327 for _, p := range parts {
328 var newParts []string
329 for _, ap := range p {
330 if strings.Index(ap, "x") != -1 {
331 opStr, vStr, err := splitComparatorVersion(ap)
332 if err != nil {
333 return nil, err
334 }
335
336 versionWildcardType := getWildcardType(vStr)
337 flatVersion := createVersionFromWildcard(vStr)
338
339 var resultOperator string
340 var shouldIncrementVersion bool
341 switch opStr {
342 case ">":
343 resultOperator = ">="
344 shouldIncrementVersion = true
345 case ">=":
346 resultOperator = ">="
347 case "<":
348 resultOperator = "<"
349 case "<=":
350 resultOperator = "<"
351 shouldIncrementVersion = true
352 case "", "=", "==":
353 newParts = append(newParts, ">="+flatVersion)
354 resultOperator = "<"
355 shouldIncrementVersion = true
356 case "!=", "!":
357 newParts = append(newParts, "<"+flatVersion)
358 resultOperator = ">="
359 shouldIncrementVersion = true
360 }
361
362 var resultVersion string
363 if shouldIncrementVersion {
364 switch versionWildcardType {
365 case patchWildcard:
366 resultVersion, _ = incrementMinorVersion(flatVersion)
367 case minorWildcard:
368 resultVersion, _ = incrementMajorVersion(flatVersion)
369 }
370 } else {
371 resultVersion = flatVersion
372 }
373
374 ap = resultOperator + resultVersion
375 }
376 newParts = append(newParts, ap)
377 }
378 expandedParts = append(expandedParts, newParts)
379 }
380
381 return expandedParts, nil
382}
383
384func parseComparator(s string) comparator {
385 switch s {
386 case "==":
387 fallthrough
388 case "":
389 fallthrough
390 case "=":
391 return compEQ
392 case ">":
393 return compGT
394 case ">=":
395 return compGE
396 case "<":
397 return compLT
398 case "<=":
399 return compLE
400 case "!":
401 fallthrough
402 case "!=":
403 return compNE
404 }
405
406 return nil
407}
408
409// MustParseRange is like ParseRange but panics if the range cannot be parsed.
410func MustParseRange(s string) Range {
411 r, err := ParseRange(s)
412 if err != nil {
413 panic(`semver: ParseRange(` + s + `): ` + err.Error())
414 }
415 return r
416}
diff --git a/vendor/github.com/blang/semver/semver.go b/vendor/github.com/blang/semver/semver.go
new file mode 100644
index 0000000..8ee0842
--- /dev/null
+++ b/vendor/github.com/blang/semver/semver.go
@@ -0,0 +1,418 @@
1package semver
2
3import (
4 "errors"
5 "fmt"
6 "strconv"
7 "strings"
8)
9
10const (
11 numbers string = "0123456789"
12 alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"
13 alphanum = alphas + numbers
14)
15
16// SpecVersion is the latest fully supported spec version of semver
17var SpecVersion = Version{
18 Major: 2,
19 Minor: 0,
20 Patch: 0,
21}
22
23// Version represents a semver compatible version
24type Version struct {
25 Major uint64
26 Minor uint64
27 Patch uint64
28 Pre []PRVersion
29 Build []string //No Precendence
30}
31
32// Version to string
33func (v Version) String() string {
34 b := make([]byte, 0, 5)
35 b = strconv.AppendUint(b, v.Major, 10)
36 b = append(b, '.')
37 b = strconv.AppendUint(b, v.Minor, 10)
38 b = append(b, '.')
39 b = strconv.AppendUint(b, v.Patch, 10)
40
41 if len(v.Pre) > 0 {
42 b = append(b, '-')
43 b = append(b, v.Pre[0].String()...)
44
45 for _, pre := range v.Pre[1:] {
46 b = append(b, '.')
47 b = append(b, pre.String()...)
48 }
49 }
50
51 if len(v.Build) > 0 {
52 b = append(b, '+')
53 b = append(b, v.Build[0]...)
54
55 for _, build := range v.Build[1:] {
56 b = append(b, '.')
57 b = append(b, build...)
58 }
59 }
60
61 return string(b)
62}
63
64// Equals checks if v is equal to o.
65func (v Version) Equals(o Version) bool {
66 return (v.Compare(o) == 0)
67}
68
69// EQ checks if v is equal to o.
70func (v Version) EQ(o Version) bool {
71 return (v.Compare(o) == 0)
72}
73
74// NE checks if v is not equal to o.
75func (v Version) NE(o Version) bool {
76 return (v.Compare(o) != 0)
77}
78
79// GT checks if v is greater than o.
80func (v Version) GT(o Version) bool {
81 return (v.Compare(o) == 1)
82}
83
84// GTE checks if v is greater than or equal to o.
85func (v Version) GTE(o Version) bool {
86 return (v.Compare(o) >= 0)
87}
88
89// GE checks if v is greater than or equal to o.
90func (v Version) GE(o Version) bool {
91 return (v.Compare(o) >= 0)
92}
93
94// LT checks if v is less than o.
95func (v Version) LT(o Version) bool {
96 return (v.Compare(o) == -1)
97}
98
99// LTE checks if v is less than or equal to o.
100func (v Version) LTE(o Version) bool {
101 return (v.Compare(o) <= 0)
102}
103
104// LE checks if v is less than or equal to o.
105func (v Version) LE(o Version) bool {
106 return (v.Compare(o) <= 0)
107}
108
109// Compare compares Versions v to o:
110// -1 == v is less than o
111// 0 == v is equal to o
112// 1 == v is greater than o
113func (v Version) Compare(o Version) int {
114 if v.Major != o.Major {
115 if v.Major > o.Major {
116 return 1
117 }
118 return -1
119 }
120 if v.Minor != o.Minor {
121 if v.Minor > o.Minor {
122 return 1
123 }
124 return -1
125 }
126 if v.Patch != o.Patch {
127 if v.Patch > o.Patch {
128 return 1
129 }
130 return -1
131 }
132
133 // Quick comparison if a version has no prerelease versions
134 if len(v.Pre) == 0 && len(o.Pre) == 0 {
135 return 0
136 } else if len(v.Pre) == 0 && len(o.Pre) > 0 {
137 return 1
138 } else if len(v.Pre) > 0 && len(o.Pre) == 0 {
139 return -1
140 }
141
142 i := 0
143 for ; i < len(v.Pre) && i < len(o.Pre); i++ {
144 if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 {
145 continue
146 } else if comp == 1 {
147 return 1
148 } else {
149 return -1
150 }
151 }
152
153 // If all pr versions are the equal but one has further prversion, this one greater
154 if i == len(v.Pre) && i == len(o.Pre) {
155 return 0
156 } else if i == len(v.Pre) && i < len(o.Pre) {
157 return -1
158 } else {
159 return 1
160 }
161
162}
163
164// Validate validates v and returns error in case
165func (v Version) Validate() error {
166 // Major, Minor, Patch already validated using uint64
167
168 for _, pre := range v.Pre {
169 if !pre.IsNum { //Numeric prerelease versions already uint64
170 if len(pre.VersionStr) == 0 {
171 return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr)
172 }
173 if !containsOnly(pre.VersionStr, alphanum) {
174 return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr)
175 }
176 }
177 }
178
179 for _, build := range v.Build {
180 if len(build) == 0 {
181 return fmt.Errorf("Build meta data can not be empty %q", build)
182 }
183 if !containsOnly(build, alphanum) {
184 return fmt.Errorf("Invalid character(s) found in build meta data %q", build)
185 }
186 }
187
188 return nil
189}
190
191// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error
192func New(s string) (vp *Version, err error) {
193 v, err := Parse(s)
194 vp = &v
195 return
196}
197
198// Make is an alias for Parse, parses version string and returns a validated Version or error
199func Make(s string) (Version, error) {
200 return Parse(s)
201}
202
203// ParseTolerant allows for certain version specifications that do not strictly adhere to semver
204// specs to be parsed by this library. It does so by normalizing versions before passing them to
205// Parse(). It currently trims spaces, removes a "v" prefix, and adds a 0 patch number to versions
206// with only major and minor components specified
207func ParseTolerant(s string) (Version, error) {
208 s = strings.TrimSpace(s)
209 s = strings.TrimPrefix(s, "v")
210
211 // Split into major.minor.(patch+pr+meta)
212 parts := strings.SplitN(s, ".", 3)
213 if len(parts) < 3 {
214 if strings.ContainsAny(parts[len(parts)-1], "+-") {
215 return Version{}, errors.New("Short version cannot contain PreRelease/Build meta data")
216 }
217 for len(parts) < 3 {
218 parts = append(parts, "0")
219 }
220 s = strings.Join(parts, ".")
221 }
222
223 return Parse(s)
224}
225
226// Parse parses version string and returns a validated Version or error
227func Parse(s string) (Version, error) {
228 if len(s) == 0 {
229 return Version{}, errors.New("Version string empty")
230 }
231
232 // Split into major.minor.(patch+pr+meta)
233 parts := strings.SplitN(s, ".", 3)
234 if len(parts) != 3 {
235 return Version{}, errors.New("No Major.Minor.Patch elements found")
236 }
237
238 // Major
239 if !containsOnly(parts[0], numbers) {
240 return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0])
241 }
242 if hasLeadingZeroes(parts[0]) {
243 return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0])
244 }
245 major, err := strconv.ParseUint(parts[0], 10, 64)
246 if err != nil {
247 return Version{}, err
248 }
249
250 // Minor
251 if !containsOnly(parts[1], numbers) {
252 return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1])
253 }
254 if hasLeadingZeroes(parts[1]) {
255 return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1])
256 }
257 minor, err := strconv.ParseUint(parts[1], 10, 64)
258 if err != nil {
259 return Version{}, err
260 }
261
262 v := Version{}
263 v.Major = major
264 v.Minor = minor
265
266 var build, prerelease []string
267 patchStr := parts[2]
268
269 if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 {
270 build = strings.Split(patchStr[buildIndex+1:], ".")
271 patchStr = patchStr[:buildIndex]
272 }
273
274 if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 {
275 prerelease = strings.Split(patchStr[preIndex+1:], ".")
276 patchStr = patchStr[:preIndex]
277 }
278
279 if !containsOnly(patchStr, numbers) {
280 return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr)
281 }
282 if hasLeadingZeroes(patchStr) {
283 return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr)
284 }
285 patch, err := strconv.ParseUint(patchStr, 10, 64)
286 if err != nil {
287 return Version{}, err
288 }
289
290 v.Patch = patch
291
292 // Prerelease
293 for _, prstr := range prerelease {
294 parsedPR, err := NewPRVersion(prstr)
295 if err != nil {
296 return Version{}, err
297 }
298 v.Pre = append(v.Pre, parsedPR)
299 }
300
301 // Build meta data
302 for _, str := range build {
303 if len(str) == 0 {
304 return Version{}, errors.New("Build meta data is empty")
305 }
306 if !containsOnly(str, alphanum) {
307 return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str)
308 }
309 v.Build = append(v.Build, str)
310 }
311
312 return v, nil
313}
314
315// MustParse is like Parse but panics if the version cannot be parsed.
316func MustParse(s string) Version {
317 v, err := Parse(s)
318 if err != nil {
319 panic(`semver: Parse(` + s + `): ` + err.Error())
320 }
321 return v
322}
323
324// PRVersion represents a PreRelease Version
325type PRVersion struct {
326 VersionStr string
327 VersionNum uint64
328 IsNum bool
329}
330
331// NewPRVersion creates a new valid prerelease version
332func NewPRVersion(s string) (PRVersion, error) {
333 if len(s) == 0 {
334 return PRVersion{}, errors.New("Prerelease is empty")
335 }
336 v := PRVersion{}
337 if containsOnly(s, numbers) {
338 if hasLeadingZeroes(s) {
339 return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
340 }
341 num, err := strconv.ParseUint(s, 10, 64)
342
343 // Might never be hit, but just in case
344 if err != nil {
345 return PRVersion{}, err
346 }
347 v.VersionNum = num
348 v.IsNum = true
349 } else if containsOnly(s, alphanum) {
350 v.VersionStr = s
351 v.IsNum = false
352 } else {
353 return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
354 }
355 return v, nil
356}
357
358// IsNumeric checks if prerelease-version is numeric
359func (v PRVersion) IsNumeric() bool {
360 return v.IsNum
361}
362
363// Compare compares two PreRelease Versions v and o:
364// -1 == v is less than o
365// 0 == v is equal to o
366// 1 == v is greater than o
367func (v PRVersion) Compare(o PRVersion) int {
368 if v.IsNum && !o.IsNum {
369 return -1
370 } else if !v.IsNum && o.IsNum {
371 return 1
372 } else if v.IsNum && o.IsNum {
373 if v.VersionNum == o.VersionNum {
374 return 0
375 } else if v.VersionNum > o.VersionNum {
376 return 1
377 } else {
378 return -1
379 }
380 } else { // both are Alphas
381 if v.VersionStr == o.VersionStr {
382 return 0
383 } else if v.VersionStr > o.VersionStr {
384 return 1
385 } else {
386 return -1
387 }
388 }
389}
390
391// PreRelease version to string
392func (v PRVersion) String() string {
393 if v.IsNum {
394 return strconv.FormatUint(v.VersionNum, 10)
395 }
396 return v.VersionStr
397}
398
399func containsOnly(s string, set string) bool {
400 return strings.IndexFunc(s, func(r rune) bool {
401 return !strings.ContainsRune(set, r)
402 }) == -1
403}
404
405func hasLeadingZeroes(s string) bool {
406 return len(s) > 1 && s[0] == '0'
407}
408
409// NewBuildVersion creates a new valid build version
410func NewBuildVersion(s string) (string, error) {
411 if len(s) == 0 {
412 return "", errors.New("Buildversion is empty")
413 }
414 if !containsOnly(s, alphanum) {
415 return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s)
416 }
417 return s, nil
418}
diff --git a/vendor/github.com/blang/semver/sort.go b/vendor/github.com/blang/semver/sort.go
new file mode 100644
index 0000000..e18f880
--- /dev/null
+++ b/vendor/github.com/blang/semver/sort.go
@@ -0,0 +1,28 @@
1package semver
2
3import (
4 "sort"
5)
6
7// Versions represents multiple versions.
8type Versions []Version
9
10// Len returns length of version collection
11func (s Versions) Len() int {
12 return len(s)
13}
14
15// Swap swaps two versions inside the collection by its indices
16func (s Versions) Swap(i, j int) {
17 s[i], s[j] = s[j], s[i]
18}
19
20// Less checks if version at index i is less than version at index j
21func (s Versions) Less(i, j int) bool {
22 return s[i].LT(s[j])
23}
24
25// Sort sorts a slice of versions
26func Sort(versions []Version) {
27 sort.Sort(Versions(versions))
28}
diff --git a/vendor/github.com/blang/semver/sql.go b/vendor/github.com/blang/semver/sql.go
new file mode 100644
index 0000000..eb4d802
--- /dev/null
+++ b/vendor/github.com/blang/semver/sql.go
@@ -0,0 +1,30 @@
1package semver
2
3import (
4 "database/sql/driver"
5 "fmt"
6)
7
8// Scan implements the database/sql.Scanner interface.
9func (v *Version) Scan(src interface{}) (err error) {
10 var str string
11 switch src := src.(type) {
12 case string:
13 str = src
14 case []byte:
15 str = string(src)
16 default:
17 return fmt.Errorf("Version.Scan: cannot convert %T to string.", src)
18 }
19
20 if t, err := Parse(str); err == nil {
21 *v = t
22 }
23
24 return
25}
26
27// Value implements the database/sql/driver.Valuer interface.
28func (v Version) Value() (driver.Value, error) {
29 return v.String(), nil
30}
diff --git a/vendor/github.com/hashicorp/go-cleanhttp/LICENSE b/vendor/github.com/hashicorp/go-cleanhttp/LICENSE
new file mode 100644
index 0000000..e87a115
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-cleanhttp/LICENSE
@@ -0,0 +1,363 @@
1Mozilla Public License, version 2.0
2
31. Definitions
4
51.1. "Contributor"
6
7 means each individual or legal entity that creates, contributes to the
8 creation of, or owns Covered Software.
9
101.2. "Contributor Version"
11
12 means the combination of the Contributions of others (if any) used by a
13 Contributor and that particular Contributor's Contribution.
14
151.3. "Contribution"
16
17 means Covered Software of a particular Contributor.
18
191.4. "Covered Software"
20
21 means Source Code Form to which the initial Contributor has attached the
22 notice in Exhibit A, the Executable Form of such Source Code Form, and
23 Modifications of such Source Code Form, in each case including portions
24 thereof.
25
261.5. "Incompatible With Secondary Licenses"
27 means
28
29 a. that the initial Contributor has attached the notice described in
30 Exhibit B to the Covered Software; or
31
32 b. that the Covered Software was made available under the terms of
33 version 1.1 or earlier of the License, but not also under the terms of
34 a Secondary License.
35
361.6. "Executable Form"
37
38 means any form of the work other than Source Code Form.
39
401.7. "Larger Work"
41
42 means a work that combines Covered Software with other material, in a
43 separate file or files, that is not Covered Software.
44
451.8. "License"
46
47 means this document.
48
491.9. "Licensable"
50
51 means having the right to grant, to the maximum extent possible, whether
52 at the time of the initial grant or subsequently, any and all of the
53 rights conveyed by this License.
54
551.10. "Modifications"
56
57 means any of the following:
58
59 a. any file in Source Code Form that results from an addition to,
60 deletion from, or modification of the contents of Covered Software; or
61
62 b. any new file in Source Code Form that contains any Covered Software.
63
641.11. "Patent Claims" of a Contributor
65
66 means any patent claim(s), including without limitation, method,
67 process, and apparatus claims, in any patent Licensable by such
68 Contributor that would be infringed, but for the grant of the License,
69 by the making, using, selling, offering for sale, having made, import,
70 or transfer of either its Contributions or its Contributor Version.
71
721.12. "Secondary License"
73
74 means either the GNU General Public License, Version 2.0, the GNU Lesser
75 General Public License, Version 2.1, the GNU Affero General Public
76 License, Version 3.0, or any later versions of those licenses.
77
781.13. "Source Code Form"
79
80 means the form of the work preferred for making modifications.
81
821.14. "You" (or "Your")
83
84 means an individual or a legal entity exercising rights under this
85 License. For legal entities, "You" includes any entity that controls, is
86 controlled by, or is under common control with You. For purposes of this
87 definition, "control" means (a) the power, direct or indirect, to cause
88 the direction or management of such entity, whether by contract or
89 otherwise, or (b) ownership of more than fifty percent (50%) of the
90 outstanding shares or beneficial ownership of such entity.
91
92
932. License Grants and Conditions
94
952.1. Grants
96
97 Each Contributor hereby grants You a world-wide, royalty-free,
98 non-exclusive license:
99
100 a. under intellectual property rights (other than patent or trademark)
101 Licensable by such Contributor to use, reproduce, make available,
102 modify, display, perform, distribute, and otherwise exploit its
103 Contributions, either on an unmodified basis, with Modifications, or
104 as part of a Larger Work; and
105
106 b. under Patent Claims of such Contributor to make, use, sell, offer for
107 sale, have made, import, and otherwise transfer either its
108 Contributions or its Contributor Version.
109
1102.2. Effective Date
111
112 The licenses granted in Section 2.1 with respect to any Contribution
113 become effective for each Contribution on the date the Contributor first
114 distributes such Contribution.
115
1162.3. Limitations on Grant Scope
117
118 The licenses granted in this Section 2 are the only rights granted under
119 this License. No additional rights or licenses will be implied from the
120 distribution or licensing of Covered Software under this License.
121 Notwithstanding Section 2.1(b) above, no patent license is granted by a
122 Contributor:
123
124 a. for any code that a Contributor has removed from Covered Software; or
125
126 b. for infringements caused by: (i) Your and any other third party's
127 modifications of Covered Software, or (ii) the combination of its
128 Contributions with other software (except as part of its Contributor
129 Version); or
130
131 c. under Patent Claims infringed by Covered Software in the absence of
132 its Contributions.
133
134 This License does not grant any rights in the trademarks, service marks,
135 or logos of any Contributor (except as may be necessary to comply with
136 the notice requirements in Section 3.4).
137
1382.4. Subsequent Licenses
139
140 No Contributor makes additional grants as a result of Your choice to
141 distribute the Covered Software under a subsequent version of this
142 License (see Section 10.2) or under the terms of a Secondary License (if
143 permitted under the terms of Section 3.3).
144
1452.5. Representation
146
147 Each Contributor represents that the Contributor believes its
148 Contributions are its original creation(s) or it has sufficient rights to
149 grant the rights to its Contributions conveyed by this License.
150
1512.6. Fair Use
152
153 This License is not intended to limit any rights You have under
154 applicable copyright doctrines of fair use, fair dealing, or other
155 equivalents.
156
1572.7. Conditions
158
159 Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
160 Section 2.1.
161
162
1633. Responsibilities
164
1653.1. Distribution of Source Form
166
167 All distribution of Covered Software in Source Code Form, including any
168 Modifications that You create or to which You contribute, must be under
169 the terms of this License. You must inform recipients that the Source
170 Code Form of the Covered Software is governed by the terms of this
171 License, and how they can obtain a copy of this License. You may not
172 attempt to alter or restrict the recipients' rights in the Source Code
173 Form.
174
1753.2. Distribution of Executable Form
176
177 If You distribute Covered Software in Executable Form then:
178
179 a. such Covered Software must also be made available in Source Code Form,
180 as described in Section 3.1, and You must inform recipients of the
181 Executable Form how they can obtain a copy of such Source Code Form by
182 reasonable means in a timely manner, at a charge no more than the cost
183 of distribution to the recipient; and
184
185 b. You may distribute such Executable Form under the terms of this
186 License, or sublicense it under different terms, provided that the
187 license for the Executable Form does not attempt to limit or alter the
188 recipients' rights in the Source Code Form under this License.
189
1903.3. Distribution of a Larger Work
191
192 You may create and distribute a Larger Work under terms of Your choice,
193 provided that You also comply with the requirements of this License for
194 the Covered Software. If the Larger Work is a combination of Covered
195 Software with a work governed by one or more Secondary Licenses, and the
196 Covered Software is not Incompatible With Secondary Licenses, this
197 License permits You to additionally distribute such Covered Software
198 under the terms of such Secondary License(s), so that the recipient of
199 the Larger Work may, at their option, further distribute the Covered
200 Software under the terms of either this License or such Secondary
201 License(s).
202
2033.4. Notices
204
205 You may not remove or alter the substance of any license notices
206 (including copyright notices, patent notices, disclaimers of warranty, or
207 limitations of liability) contained within the Source Code Form of the
208 Covered Software, except that You may alter any license notices to the
209 extent required to remedy known factual inaccuracies.
210
2113.5. Application of Additional Terms
212
213 You may choose to offer, and to charge a fee for, warranty, support,
214 indemnity or liability obligations to one or more recipients of Covered
215 Software. However, You may do so only on Your own behalf, and not on
216 behalf of any Contributor. You must make it absolutely clear that any
217 such warranty, support, indemnity, or liability obligation is offered by
218 You alone, and You hereby agree to indemnify every Contributor for any
219 liability incurred by such Contributor as a result of warranty, support,
220 indemnity or liability terms You offer. You may include additional
221 disclaimers of warranty and limitations of liability specific to any
222 jurisdiction.
223
2244. Inability to Comply Due to Statute or Regulation
225
226 If it is impossible for You to comply with any of the terms of this License
227 with respect to some or all of the Covered Software due to statute,
228 judicial order, or regulation then You must: (a) comply with the terms of
229 this License to the maximum extent possible; and (b) describe the
230 limitations and the code they affect. Such description must be placed in a
231 text file included with all distributions of the Covered Software under
232 this License. Except to the extent prohibited by statute or regulation,
233 such description must be sufficiently detailed for a recipient of ordinary
234 skill to be able to understand it.
235
2365. Termination
237
2385.1. The rights granted under this License will terminate automatically if You
239 fail to comply with any of its terms. However, if You become compliant,
240 then the rights granted under this License from a particular Contributor
241 are reinstated (a) provisionally, unless and until such Contributor
242 explicitly and finally terminates Your grants, and (b) on an ongoing
243 basis, if such Contributor fails to notify You of the non-compliance by
244 some reasonable means prior to 60 days after You have come back into
245 compliance. Moreover, Your grants from a particular Contributor are
246 reinstated on an ongoing basis if such Contributor notifies You of the
247 non-compliance by some reasonable means, this is the first time You have
248 received notice of non-compliance with this License from such
249 Contributor, and You become compliant prior to 30 days after Your receipt
250 of the notice.
251
2525.2. If You initiate litigation against any entity by asserting a patent
253 infringement claim (excluding declaratory judgment actions,
254 counter-claims, and cross-claims) alleging that a Contributor Version
255 directly or indirectly infringes any patent, then the rights granted to
256 You by any and all Contributors for the Covered Software under Section
257 2.1 of this License shall terminate.
258
2595.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
260 license agreements (excluding distributors and resellers) which have been
261 validly granted by You or Your distributors under this License prior to
262 termination shall survive termination.
263
2646. Disclaimer of Warranty
265
266 Covered Software is provided under this License on an "as is" basis,
267 without warranty of any kind, either expressed, implied, or statutory,
268 including, without limitation, warranties that the Covered Software is free
269 of defects, merchantable, fit for a particular purpose or non-infringing.
270 The entire risk as to the quality and performance of the Covered Software
271 is with You. Should any Covered Software prove defective in any respect,
272 You (not any Contributor) assume the cost of any necessary servicing,
273 repair, or correction. This disclaimer of warranty constitutes an essential
274 part of this License. No use of any Covered Software is authorized under
275 this License except under this disclaimer.
276
2777. Limitation of Liability
278
279 Under no circumstances and under no legal theory, whether tort (including
280 negligence), contract, or otherwise, shall any Contributor, or anyone who
281 distributes Covered Software as permitted above, be liable to You for any
282 direct, indirect, special, incidental, or consequential damages of any
283 character including, without limitation, damages for lost profits, loss of
284 goodwill, work stoppage, computer failure or malfunction, or any and all
285 other commercial damages or losses, even if such party shall have been
286 informed of the possibility of such damages. This limitation of liability
287 shall not apply to liability for death or personal injury resulting from
288 such party's negligence to the extent applicable law prohibits such
289 limitation. Some jurisdictions do not allow the exclusion or limitation of
290 incidental or consequential damages, so this exclusion and limitation may
291 not apply to You.
292
2938. Litigation
294
295 Any litigation relating to this License may be brought only in the courts
296 of a jurisdiction where the defendant maintains its principal place of
297 business and such litigation shall be governed by laws of that
298 jurisdiction, without reference to its conflict-of-law provisions. Nothing
299 in this Section shall prevent a party's ability to bring cross-claims or
300 counter-claims.
301
3029. Miscellaneous
303
304 This License represents the complete agreement concerning the subject
305 matter hereof. If any provision of this License is held to be
306 unenforceable, such provision shall be reformed only to the extent
307 necessary to make it enforceable. Any law or regulation which provides that
308 the language of a contract shall be construed against the drafter shall not
309 be used to construe this License against a Contributor.
310
311
31210. Versions of the License
313
31410.1. New Versions
315
316 Mozilla Foundation is the license steward. Except as provided in Section
317 10.3, no one other than the license steward has the right to modify or
318 publish new versions of this License. Each version will be given a
319 distinguishing version number.
320
32110.2. Effect of New Versions
322
323 You may distribute the Covered Software under the terms of the version
324 of the License under which You originally received the Covered Software,
325 or under the terms of any subsequent version published by the license
326 steward.
327
32810.3. Modified Versions
329
330 If you create software not governed by this License, and you want to
331 create a new license for such software, you may create and use a
332 modified version of this License if you rename the license and remove
333 any references to the name of the license steward (except to note that
334 such modified license differs from this License).
335
33610.4. Distributing Source Code Form that is Incompatible With Secondary
337 Licenses If You choose to distribute Source Code Form that is
338 Incompatible With Secondary Licenses under the terms of this version of
339 the License, the notice described in Exhibit B of this License must be
340 attached.
341
342Exhibit A - Source Code Form License Notice
343
344 This Source Code Form is subject to the
345 terms of the Mozilla Public License, v.
346 2.0. If a copy of the MPL was not
347 distributed with this file, You can
348 obtain one at
349 http://mozilla.org/MPL/2.0/.
350
351If it is not possible or desirable to put the notice in a particular file,
352then You may include the notice in a location (such as a LICENSE file in a
353relevant directory) where a recipient would be likely to look for such a
354notice.
355
356You may add additional accurate notices of copyright ownership.
357
358Exhibit B - "Incompatible With Secondary Licenses" Notice
359
360 This Source Code Form is "Incompatible
361 With Secondary Licenses", as defined by
362 the Mozilla Public License, v. 2.0.
363
diff --git a/vendor/github.com/hashicorp/go-cleanhttp/README.md b/vendor/github.com/hashicorp/go-cleanhttp/README.md
new file mode 100644
index 0000000..036e531
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-cleanhttp/README.md
@@ -0,0 +1,30 @@
1# cleanhttp
2
3Functions for accessing "clean" Go http.Client values
4
5-------------
6
7The Go standard library contains a default `http.Client` called
8`http.DefaultClient`. It is a common idiom in Go code to start with
9`http.DefaultClient` and tweak it as necessary, and in fact, this is
10encouraged; from the `http` package documentation:
11
12> The Client's Transport typically has internal state (cached TCP connections),
13so Clients should be reused instead of created as needed. Clients are safe for
14concurrent use by multiple goroutines.
15
16Unfortunately, this is a shared value, and it is not uncommon for libraries to
17assume that they are free to modify it at will. With enough dependencies, it
18can be very easy to encounter strange problems and race conditions due to
19manipulation of this shared value across libraries and goroutines (clients are
20safe for concurrent use, but writing values to the client struct itself is not
21protected).
22
23Making things worse is the fact that a bare `http.Client` will use a default
24`http.Transport` called `http.DefaultTransport`, which is another global value
25that behaves the same way. So it is not simply enough to replace
26`http.DefaultClient` with `&http.Client{}`.
27
28This repository provides some simple functions to get a "clean" `http.Client`
29-- one that uses the same default values as the Go standard library, but
30returns a client that does not share any state with other clients.
diff --git a/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go b/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go
new file mode 100644
index 0000000..7d8a57c
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go
@@ -0,0 +1,56 @@
1package cleanhttp
2
3import (
4 "net"
5 "net/http"
6 "runtime"
7 "time"
8)
9
10// DefaultTransport returns a new http.Transport with similar default values to
11// http.DefaultTransport, but with idle connections and keepalives disabled.
12func DefaultTransport() *http.Transport {
13 transport := DefaultPooledTransport()
14 transport.DisableKeepAlives = true
15 transport.MaxIdleConnsPerHost = -1
16 return transport
17}
18
19// DefaultPooledTransport returns a new http.Transport with similar default
20// values to http.DefaultTransport. Do not use this for transient transports as
21// it can leak file descriptors over time. Only use this for transports that
22// will be re-used for the same host(s).
23func DefaultPooledTransport() *http.Transport {
24 transport := &http.Transport{
25 Proxy: http.ProxyFromEnvironment,
26 DialContext: (&net.Dialer{
27 Timeout: 30 * time.Second,
28 KeepAlive: 30 * time.Second,
29 }).DialContext,
30 MaxIdleConns: 100,
31 IdleConnTimeout: 90 * time.Second,
32 TLSHandshakeTimeout: 10 * time.Second,
33 ExpectContinueTimeout: 1 * time.Second,
34 MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1,
35 }
36 return transport
37}
38
39// DefaultClient returns a new http.Client with similar default values to
40// http.Client, but with a non-shared Transport, idle connections disabled, and
41// keepalives disabled.
42func DefaultClient() *http.Client {
43 return &http.Client{
44 Transport: DefaultTransport(),
45 }
46}
47
48// DefaultPooledClient returns a new http.Client with similar default values to
49// http.Client, but with a shared Transport. Do not use this function for
50// transient clients as it can leak file descriptors over time. Only use this
51// for clients that will be re-used for the same host(s).
52func DefaultPooledClient() *http.Client {
53 return &http.Client{
54 Transport: DefaultPooledTransport(),
55 }
56}
diff --git a/vendor/github.com/hashicorp/go-cleanhttp/doc.go b/vendor/github.com/hashicorp/go-cleanhttp/doc.go
new file mode 100644
index 0000000..0584109
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-cleanhttp/doc.go
@@ -0,0 +1,20 @@
1// Package cleanhttp offers convenience utilities for acquiring "clean"
2// http.Transport and http.Client structs.
3//
4// Values set on http.DefaultClient and http.DefaultTransport affect all
5// callers. This can have detrimental effects, esepcially in TLS contexts,
6// where client or root certificates set to talk to multiple endpoints can end
7// up displacing each other, leading to hard-to-debug issues. This package
8// provides non-shared http.Client and http.Transport structs to ensure that
9// the configuration will not be overwritten by other parts of the application
10// or dependencies.
11//
12// The DefaultClient and DefaultTransport functions disable idle connections
13// and keepalives. Without ensuring that idle connections are closed before
14// garbage collection, short-term clients/transports can leak file descriptors,
15// eventually leading to "too many open files" errors. If you will be
16// connecting to the same hosts repeatedly from the same client, you can use
17// DefaultPooledClient to receive a client that has connection pooling
18// semantics similar to http.DefaultClient.
19//
20package cleanhttp
diff --git a/vendor/github.com/hashicorp/terraform/config/config.go b/vendor/github.com/hashicorp/terraform/config/config.go
index a157824..3f756dc 100644
--- a/vendor/github.com/hashicorp/terraform/config/config.go
+++ b/vendor/github.com/hashicorp/terraform/config/config.go
@@ -12,6 +12,7 @@ import (
12 "github.com/hashicorp/hil" 12 "github.com/hashicorp/hil"
13 "github.com/hashicorp/hil/ast" 13 "github.com/hashicorp/hil/ast"
14 "github.com/hashicorp/terraform/helper/hilmapstructure" 14 "github.com/hashicorp/terraform/helper/hilmapstructure"
15 "github.com/hashicorp/terraform/plugin/discovery"
15 "github.com/mitchellh/reflectwalk" 16 "github.com/mitchellh/reflectwalk"
16) 17)
17 18
@@ -64,6 +65,7 @@ type Module struct {
64type ProviderConfig struct { 65type ProviderConfig struct {
65 Name string 66 Name string
66 Alias string 67 Alias string
68 Version string
67 RawConfig *RawConfig 69 RawConfig *RawConfig
68} 70}
69 71
@@ -238,6 +240,33 @@ func (r *Resource) Id() string {
238 } 240 }
239} 241}
240 242
243// ProviderFullName returns the full name of the provider for this resource,
244// which may either be specified explicitly using the "provider" meta-argument
245// or implied by the prefix on the resource type name.
246func (r *Resource) ProviderFullName() string {
247 return ResourceProviderFullName(r.Type, r.Provider)
248}
249
250// ResourceProviderFullName returns the full (dependable) name of the
251// provider for a hypothetical resource with the given resource type and
252// explicit provider string. If the explicit provider string is empty then
253// the provider name is inferred from the resource type name.
254func ResourceProviderFullName(resourceType, explicitProvider string) string {
255 if explicitProvider != "" {
256 return explicitProvider
257 }
258
259 idx := strings.IndexRune(resourceType, '_')
260 if idx == -1 {
261 // If no underscores, the resource name is assumed to be
262 // also the provider name, e.g. if the provider exposes
263 // only a single resource of each type.
264 return resourceType
265 }
266
267 return resourceType[:idx]
268}
269
241// Validate does some basic semantic checking of the configuration. 270// Validate does some basic semantic checking of the configuration.
242func (c *Config) Validate() error { 271func (c *Config) Validate() error {
243 if c == nil { 272 if c == nil {
@@ -349,7 +378,8 @@ func (c *Config) Validate() error {
349 } 378 }
350 } 379 }
351 380
352 // Check that providers aren't declared multiple times. 381 // Check that providers aren't declared multiple times and that their
382 // version constraints, where present, are syntactically valid.
353 providerSet := make(map[string]struct{}) 383 providerSet := make(map[string]struct{})
354 for _, p := range c.ProviderConfigs { 384 for _, p := range c.ProviderConfigs {
355 name := p.FullName() 385 name := p.FullName()
@@ -360,6 +390,16 @@ func (c *Config) Validate() error {
360 continue 390 continue
361 } 391 }
362 392
393 if p.Version != "" {
394 _, err := discovery.ConstraintStr(p.Version).Parse()
395 if err != nil {
396 errs = append(errs, fmt.Errorf(
397 "provider.%s: invalid version constraint %q: %s",
398 name, p.Version, err,
399 ))
400 }
401 }
402
363 providerSet[name] = struct{}{} 403 providerSet[name] = struct{}{}
364 } 404 }
365 405
diff --git a/vendor/github.com/hashicorp/terraform/config/interpolate_funcs.go b/vendor/github.com/hashicorp/terraform/config/interpolate_funcs.go
index 7b7b3f2..a298cf2 100644
--- a/vendor/github.com/hashicorp/terraform/config/interpolate_funcs.go
+++ b/vendor/github.com/hashicorp/terraform/config/interpolate_funcs.go
@@ -70,6 +70,7 @@ func Funcs() map[string]ast.Function {
70 "coalescelist": interpolationFuncCoalesceList(), 70 "coalescelist": interpolationFuncCoalesceList(),
71 "compact": interpolationFuncCompact(), 71 "compact": interpolationFuncCompact(),
72 "concat": interpolationFuncConcat(), 72 "concat": interpolationFuncConcat(),
73 "contains": interpolationFuncContains(),
73 "dirname": interpolationFuncDirname(), 74 "dirname": interpolationFuncDirname(),
74 "distinct": interpolationFuncDistinct(), 75 "distinct": interpolationFuncDistinct(),
75 "element": interpolationFuncElement(), 76 "element": interpolationFuncElement(),
@@ -356,6 +357,22 @@ func interpolationFuncCoalesceList() ast.Function {
356 } 357 }
357} 358}
358 359
360// interpolationFuncContains returns true if an element is in the list
361// and return false otherwise
362func interpolationFuncContains() ast.Function {
363 return ast.Function{
364 ArgTypes: []ast.Type{ast.TypeList, ast.TypeString},
365 ReturnType: ast.TypeBool,
366 Callback: func(args []interface{}) (interface{}, error) {
367 _, err := interpolationFuncIndex().Callback(args)
368 if err != nil {
369 return false, nil
370 }
371 return true, nil
372 },
373 }
374}
375
359// interpolationFuncConcat implements the "concat" function that concatenates 376// interpolationFuncConcat implements the "concat" function that concatenates
360// multiple lists. 377// multiple lists.
361func interpolationFuncConcat() ast.Function { 378func interpolationFuncConcat() ast.Function {
diff --git a/vendor/github.com/hashicorp/terraform/config/loader.go b/vendor/github.com/hashicorp/terraform/config/loader.go
index 0bfa89c..5dd7d46 100644
--- a/vendor/github.com/hashicorp/terraform/config/loader.go
+++ b/vendor/github.com/hashicorp/terraform/config/loader.go
@@ -194,7 +194,7 @@ func dirFiles(dir string) ([]string, []string, error) {
194 // Only care about files that are valid to load 194 // Only care about files that are valid to load
195 name := fi.Name() 195 name := fi.Name()
196 extValue := ext(name) 196 extValue := ext(name)
197 if extValue == "" || isIgnoredFile(name) { 197 if extValue == "" || IsIgnoredFile(name) {
198 continue 198 continue
199 } 199 }
200 200
@@ -215,9 +215,9 @@ func dirFiles(dir string) ([]string, []string, error) {
215 return files, overrides, nil 215 return files, overrides, nil
216} 216}
217 217
218// isIgnoredFile returns true or false depending on whether the 218// IsIgnoredFile returns true or false depending on whether the
219// provided file name is a file that should be ignored. 219// provided file name is a file that should be ignored.
220func isIgnoredFile(name string) bool { 220func IsIgnoredFile(name string) bool {
221 return strings.HasPrefix(name, ".") || // Unix-like hidden files 221 return strings.HasPrefix(name, ".") || // Unix-like hidden files
222 strings.HasSuffix(name, "~") || // vim 222 strings.HasSuffix(name, "~") || // vim
223 strings.HasPrefix(name, "#") && strings.HasSuffix(name, "#") // emacs 223 strings.HasPrefix(name, "#") && strings.HasSuffix(name, "#") // emacs
diff --git a/vendor/github.com/hashicorp/terraform/config/loader_hcl.go b/vendor/github.com/hashicorp/terraform/config/loader_hcl.go
index 9abb196..e85e493 100644
--- a/vendor/github.com/hashicorp/terraform/config/loader_hcl.go
+++ b/vendor/github.com/hashicorp/terraform/config/loader_hcl.go
@@ -17,6 +17,20 @@ type hclConfigurable struct {
17 Root *ast.File 17 Root *ast.File
18} 18}
19 19
20var ReservedResourceFields = []string{
21 "connection",
22 "count",
23 "depends_on",
24 "lifecycle",
25 "provider",
26 "provisioner",
27}
28
29var ReservedProviderFields = []string{
30 "alias",
31 "version",
32}
33
20func (t *hclConfigurable) Config() (*Config, error) { 34func (t *hclConfigurable) Config() (*Config, error) {
21 validKeys := map[string]struct{}{ 35 validKeys := map[string]struct{}{
22 "atlas": struct{}{}, 36 "atlas": struct{}{},
@@ -562,6 +576,7 @@ func loadProvidersHcl(list *ast.ObjectList) ([]*ProviderConfig, error) {
562 } 576 }
563 577
564 delete(config, "alias") 578 delete(config, "alias")
579 delete(config, "version")
565 580
566 rawConfig, err := NewRawConfig(config) 581 rawConfig, err := NewRawConfig(config)
567 if err != nil { 582 if err != nil {
@@ -583,9 +598,22 @@ func loadProvidersHcl(list *ast.ObjectList) ([]*ProviderConfig, error) {
583 } 598 }
584 } 599 }
585 600
601 // If we have a version field then extract it
602 var version string
603 if a := listVal.Filter("version"); len(a.Items) > 0 {
604 err := hcl.DecodeObject(&version, a.Items[0].Val)
605 if err != nil {
606 return nil, fmt.Errorf(
607 "Error reading version for provider[%s]: %s",
608 n,
609 err)
610 }
611 }
612
586 result = append(result, &ProviderConfig{ 613 result = append(result, &ProviderConfig{
587 Name: n, 614 Name: n,
588 Alias: alias, 615 Alias: alias,
616 Version: version,
589 RawConfig: rawConfig, 617 RawConfig: rawConfig,
590 }) 618 })
591 } 619 }
diff --git a/vendor/github.com/hashicorp/terraform/config/module/tree.go b/vendor/github.com/hashicorp/terraform/config/module/tree.go
index b6f90fd..4b0b153 100644
--- a/vendor/github.com/hashicorp/terraform/config/module/tree.go
+++ b/vendor/github.com/hashicorp/terraform/config/module/tree.go
@@ -92,6 +92,25 @@ func (t *Tree) Children() map[string]*Tree {
92 return t.children 92 return t.children
93} 93}
94 94
95// DeepEach calls the provided callback for the receiver and then all of
96// its descendents in the tree, allowing an operation to be performed on
97// all modules in the tree.
98//
99// Parents will be visited before their children but otherwise the order is
100// not defined.
101func (t *Tree) DeepEach(cb func(*Tree)) {
102 t.lock.RLock()
103 defer t.lock.RUnlock()
104 t.deepEach(cb)
105}
106
107func (t *Tree) deepEach(cb func(*Tree)) {
108 cb(t)
109 for _, c := range t.children {
110 c.deepEach(cb)
111 }
112}
113
95// Loaded says whether or not this tree has been loaded or not yet. 114// Loaded says whether or not this tree has been loaded or not yet.
96func (t *Tree) Loaded() bool { 115func (t *Tree) Loaded() bool {
97 t.lock.RLock() 116 t.lock.RLock()
diff --git a/vendor/github.com/hashicorp/terraform/config/providers.go b/vendor/github.com/hashicorp/terraform/config/providers.go
new file mode 100644
index 0000000..7a50782
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/config/providers.go
@@ -0,0 +1,103 @@
1package config
2
3import "github.com/blang/semver"
4
5// ProviderVersionConstraint presents a constraint for a particular
6// provider, identified by its full name.
7type ProviderVersionConstraint struct {
8 Constraint string
9 ProviderType string
10}
11
12// ProviderVersionConstraints is a map from provider full name to its associated
13// ProviderVersionConstraint, as produced by Config.RequiredProviders.
14type ProviderVersionConstraints map[string]ProviderVersionConstraint
15
16// RequiredProviders returns the ProviderVersionConstraints for this
17// module.
18//
19// This includes both providers that are explicitly requested by provider
20// blocks and those that are used implicitly by instantiating one of their
21// resource types. In the latter case, the returned semver Range will
22// accept any version of the provider.
23func (c *Config) RequiredProviders() ProviderVersionConstraints {
24 ret := make(ProviderVersionConstraints, len(c.ProviderConfigs))
25
26 configs := c.ProviderConfigsByFullName()
27
28 // In order to find the *implied* dependencies (those without explicit
29 // "provider" blocks) we need to walk over all of the resources and
30 // cross-reference with the provider configs.
31 for _, rc := range c.Resources {
32 providerName := rc.ProviderFullName()
33 var providerType string
34
35 // Default to (effectively) no constraint whatsoever, but we might
36 // override if there's an explicit constraint in config.
37 constraint := ">=0.0.0"
38
39 config, ok := configs[providerName]
40 if ok {
41 if config.Version != "" {
42 constraint = config.Version
43 }
44 providerType = config.Name
45 } else {
46 providerType = providerName
47 }
48
49 ret[providerName] = ProviderVersionConstraint{
50 ProviderType: providerType,
51 Constraint: constraint,
52 }
53 }
54
55 return ret
56}
57
58// RequiredRanges returns a semver.Range for each distinct provider type in
59// the constraint map. If the same provider type appears more than once
60// (e.g. because aliases are in use) then their respective constraints are
61// combined such that they must *all* apply.
62//
63// The result of this method can be passed to the
64// PluginMetaSet.ConstrainVersions method within the plugin/discovery
65// package in order to filter down the available plugins to those which
66// satisfy the given constraints.
67//
68// This function will panic if any of the constraints within cannot be
69// parsed as semver ranges. This is guaranteed to never happen for a
70// constraint set that was built from a configuration that passed validation.
71func (cons ProviderVersionConstraints) RequiredRanges() map[string]semver.Range {
72 ret := make(map[string]semver.Range, len(cons))
73
74 for _, con := range cons {
75 spec := semver.MustParseRange(con.Constraint)
76 if existing, exists := ret[con.ProviderType]; exists {
77 ret[con.ProviderType] = existing.AND(spec)
78 } else {
79 ret[con.ProviderType] = spec
80 }
81 }
82
83 return ret
84}
85
86// ProviderConfigsByFullName returns a map from provider full names (as
87// returned by ProviderConfig.FullName()) to the corresponding provider
88// configs.
89//
90// This function returns no new information than what's already in
91// c.ProviderConfigs, but returns it in a more convenient shape. If there
92// is more than one provider config with the same full name then the result
93// is undefined, but that is guaranteed not to happen for any config that
94// has passed validation.
95func (c *Config) ProviderConfigsByFullName() map[string]*ProviderConfig {
96 ret := make(map[string]*ProviderConfig, len(c.ProviderConfigs))
97
98 for _, pc := range c.ProviderConfigs {
99 ret[pc.FullName()] = pc
100 }
101
102 return ret
103}
diff --git a/vendor/github.com/hashicorp/terraform/flatmap/expand.go b/vendor/github.com/hashicorp/terraform/flatmap/expand.go
index e0b81b6..1449065 100644
--- a/vendor/github.com/hashicorp/terraform/flatmap/expand.go
+++ b/vendor/github.com/hashicorp/terraform/flatmap/expand.go
@@ -60,6 +60,11 @@ func expandArray(m map[string]string, prefix string) []interface{} {
60 return []interface{}{} 60 return []interface{}{}
61 } 61 }
62 62
63 // NOTE: "num" is not necessarily accurate, e.g. if a user tampers
64 // with state, so the following code should not crash when given a
65 // number of items more or less than what's given in num. The
66 // num key is mainly just a hint that this is a list or set.
67
63 // The Schema "Set" type stores its values in an array format, but 68 // The Schema "Set" type stores its values in an array format, but
64 // using numeric hash values instead of ordinal keys. Take the set 69 // using numeric hash values instead of ordinal keys. Take the set
65 // of keys regardless of value, and expand them in numeric order. 70 // of keys regardless of value, and expand them in numeric order.
@@ -101,7 +106,7 @@ func expandArray(m map[string]string, prefix string) []interface{} {
101 } 106 }
102 sort.Ints(keysList) 107 sort.Ints(keysList)
103 108
104 result := make([]interface{}, num) 109 result := make([]interface{}, len(keysList))
105 for i, key := range keysList { 110 for i, key := range keysList {
106 keyString := strconv.Itoa(key) 111 keyString := strconv.Itoa(key)
107 if computed[keyString] { 112 if computed[keyString] {
diff --git a/vendor/github.com/hashicorp/terraform/helper/resource/id.go b/vendor/github.com/hashicorp/terraform/helper/resource/id.go
index 629582b..1cde67c 100644
--- a/vendor/github.com/hashicorp/terraform/helper/resource/id.go
+++ b/vendor/github.com/hashicorp/terraform/helper/resource/id.go
@@ -1,21 +1,17 @@
1package resource 1package resource
2 2
3import ( 3import (
4 "crypto/rand"
5 "fmt" 4 "fmt"
6 "math/big" 5 "strings"
7 "sync" 6 "sync"
7 "time"
8) 8)
9 9
10const UniqueIdPrefix = `terraform-` 10const UniqueIdPrefix = `terraform-`
11 11
12// idCounter is a randomly seeded monotonic counter for generating ordered 12// idCounter is a monotonic counter for generating ordered unique ids.
13// unique ids. It uses a big.Int so we can easily increment a long numeric
14// string. The max possible hex value here with 12 random bytes is
15// "01000000000000000000000000", so there's no chance of rollover during
16// operation.
17var idMutex sync.Mutex 13var idMutex sync.Mutex
18var idCounter = big.NewInt(0).SetBytes(randomBytes(12)) 14var idCounter uint32
19 15
20// Helper for a resource to generate a unique identifier w/ default prefix 16// Helper for a resource to generate a unique identifier w/ default prefix
21func UniqueId() string { 17func UniqueId() string {
@@ -25,15 +21,20 @@ func UniqueId() string {
25// Helper for a resource to generate a unique identifier w/ given prefix 21// Helper for a resource to generate a unique identifier w/ given prefix
26// 22//
27// After the prefix, the ID consists of an incrementing 26 digit value (to match 23// After the prefix, the ID consists of an incrementing 26 digit value (to match
28// previous timestamp output). 24// previous timestamp output). After the prefix, the ID consists of a timestamp
25// and an incrementing 8 hex digit value The timestamp means that multiple IDs
26// created with the same prefix will sort in the order of their creation, even
27// across multiple terraform executions, as long as the clock is not turned back
28// between calls, and as long as any given terraform execution generates fewer
29// than 4 billion IDs.
29func PrefixedUniqueId(prefix string) string { 30func PrefixedUniqueId(prefix string) string {
31 // Be precise to 4 digits of fractional seconds, but remove the dot before the
32 // fractional seconds.
33 timestamp := strings.Replace(
34 time.Now().UTC().Format("20060102150405.0000"), ".", "", 1)
35
30 idMutex.Lock() 36 idMutex.Lock()
31 defer idMutex.Unlock() 37 defer idMutex.Unlock()
32 return fmt.Sprintf("%s%026x", prefix, idCounter.Add(idCounter, big.NewInt(1))) 38 idCounter++
33} 39 return fmt.Sprintf("%s%s%08x", prefix, timestamp, idCounter)
34
35func randomBytes(n int) []byte {
36 b := make([]byte, n)
37 rand.Read(b)
38 return b
39} 40}
diff --git a/vendor/github.com/hashicorp/terraform/helper/resource/testing.go b/vendor/github.com/hashicorp/terraform/helper/resource/testing.go
index ebdbde2..d7de1a0 100644
--- a/vendor/github.com/hashicorp/terraform/helper/resource/testing.go
+++ b/vendor/github.com/hashicorp/terraform/helper/resource/testing.go
@@ -383,11 +383,11 @@ func Test(t TestT, c TestCase) {
383 c.PreCheck() 383 c.PreCheck()
384 } 384 }
385 385
386 ctxProviders, err := testProviderFactories(c) 386 providerResolver, err := testProviderResolver(c)
387 if err != nil { 387 if err != nil {
388 t.Fatal(err) 388 t.Fatal(err)
389 } 389 }
390 opts := terraform.ContextOpts{Providers: ctxProviders} 390 opts := terraform.ContextOpts{ProviderResolver: providerResolver}
391 391
392 // A single state variable to track the lifecycle, starting with no state 392 // A single state variable to track the lifecycle, starting with no state
393 var state *terraform.State 393 var state *terraform.State
@@ -400,15 +400,22 @@ func Test(t TestT, c TestCase) {
400 var err error 400 var err error
401 log.Printf("[WARN] Test: Executing step %d", i) 401 log.Printf("[WARN] Test: Executing step %d", i)
402 402
403 // Determine the test mode to execute 403 if step.Config == "" && !step.ImportState {
404 if step.Config != "" {
405 state, err = testStepConfig(opts, state, step)
406 } else if step.ImportState {
407 state, err = testStepImportState(opts, state, step)
408 } else {
409 err = fmt.Errorf( 404 err = fmt.Errorf(
410 "unknown test mode for step. Please see TestStep docs\n\n%#v", 405 "unknown test mode for step. Please see TestStep docs\n\n%#v",
411 step) 406 step)
407 } else {
408 if step.ImportState {
409 if step.Config == "" {
410 step.Config = testProviderConfig(c)
411 }
412
413 // Can optionally set step.Config in addition to
414 // step.ImportState, to provide config for the import.
415 state, err = testStepImportState(opts, state, step)
416 } else {
417 state, err = testStepConfig(opts, state, step)
418 }
412 } 419 }
413 420
414 // If there was an error, exit 421 // If there was an error, exit
@@ -496,16 +503,29 @@ func Test(t TestT, c TestCase) {
496 } 503 }
497} 504}
498 505
499// testProviderFactories is a helper to build the ResourceProviderFactory map 506// testProviderConfig takes the list of Providers in a TestCase and returns a
507// config with only empty provider blocks. This is useful for Import, where no
508// config is provided, but the providers must be defined.
509func testProviderConfig(c TestCase) string {
510 var lines []string
511 for p := range c.Providers {
512 lines = append(lines, fmt.Sprintf("provider %q {}\n", p))
513 }
514
515 return strings.Join(lines, "")
516}
517
518// testProviderResolver is a helper to build a ResourceProviderResolver
500// with pre instantiated ResourceProviders, so that we can reset them for the 519// with pre instantiated ResourceProviders, so that we can reset them for the
501// test, while only calling the factory function once. 520// test, while only calling the factory function once.
502// Any errors are stored so that they can be returned by the factory in 521// Any errors are stored so that they can be returned by the factory in
503// terraform to match non-test behavior. 522// terraform to match non-test behavior.
504func testProviderFactories(c TestCase) (map[string]terraform.ResourceProviderFactory, error) { 523func testProviderResolver(c TestCase) (terraform.ResourceProviderResolver, error) {
505 ctxProviders := c.ProviderFactories // make(map[string]terraform.ResourceProviderFactory) 524 ctxProviders := c.ProviderFactories
506 if ctxProviders == nil { 525 if ctxProviders == nil {
507 ctxProviders = make(map[string]terraform.ResourceProviderFactory) 526 ctxProviders = make(map[string]terraform.ResourceProviderFactory)
508 } 527 }
528
509 // add any fixed providers 529 // add any fixed providers
510 for k, p := range c.Providers { 530 for k, p := range c.Providers {
511 ctxProviders[k] = terraform.ResourceProviderFactoryFixed(p) 531 ctxProviders[k] = terraform.ResourceProviderFactoryFixed(p)
@@ -527,7 +547,7 @@ func testProviderFactories(c TestCase) (map[string]terraform.ResourceProviderFac
527 } 547 }
528 } 548 }
529 549
530 return ctxProviders, nil 550 return terraform.ResourceProviderResolverFixed(ctxProviders), nil
531} 551}
532 552
533// UnitTest is a helper to force the acceptance testing harness to run in the 553// UnitTest is a helper to force the acceptance testing harness to run in the
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/provider.go b/vendor/github.com/hashicorp/terraform/helper/schema/provider.go
index d52d2f5..fb28b41 100644
--- a/vendor/github.com/hashicorp/terraform/helper/schema/provider.go
+++ b/vendor/github.com/hashicorp/terraform/helper/schema/provider.go
@@ -8,6 +8,7 @@ import (
8 "sync" 8 "sync"
9 9
10 "github.com/hashicorp/go-multierror" 10 "github.com/hashicorp/go-multierror"
11 "github.com/hashicorp/terraform/config"
11 "github.com/hashicorp/terraform/terraform" 12 "github.com/hashicorp/terraform/terraform"
12) 13)
13 14
@@ -89,6 +90,13 @@ func (p *Provider) InternalValidate() error {
89 validationErrors = multierror.Append(validationErrors, err) 90 validationErrors = multierror.Append(validationErrors, err)
90 } 91 }
91 92
93 // Provider-specific checks
94 for k, _ := range sm {
95 if isReservedProviderFieldName(k) {
96 return fmt.Errorf("%s is a reserved field name for a provider", k)
97 }
98 }
99
92 for k, r := range p.ResourcesMap { 100 for k, r := range p.ResourcesMap {
93 if err := r.InternalValidate(nil, true); err != nil { 101 if err := r.InternalValidate(nil, true); err != nil {
94 validationErrors = multierror.Append(validationErrors, fmt.Errorf("resource %s: %s", k, err)) 102 validationErrors = multierror.Append(validationErrors, fmt.Errorf("resource %s: %s", k, err))
@@ -104,6 +112,15 @@ func (p *Provider) InternalValidate() error {
104 return validationErrors 112 return validationErrors
105} 113}
106 114
115func isReservedProviderFieldName(name string) bool {
116 for _, reservedName := range config.ReservedProviderFields {
117 if name == reservedName {
118 return true
119 }
120 }
121 return false
122}
123
107// Meta returns the metadata associated with this provider that was 124// Meta returns the metadata associated with this provider that was
108// returned by the Configure call. It will be nil until Configure is called. 125// returned by the Configure call. It will be nil until Configure is called.
109func (p *Provider) Meta() interface{} { 126func (p *Provider) Meta() interface{} {
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go b/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go
index 856c675..476192e 100644
--- a/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go
+++ b/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go
@@ -43,7 +43,7 @@ type Provisioner struct {
43 43
44 // ValidateFunc is a function for extended validation. This is optional 44 // ValidateFunc is a function for extended validation. This is optional
45 // and should be used when individual field validation is not enough. 45 // and should be used when individual field validation is not enough.
46 ValidateFunc func(*ResourceData) ([]string, []error) 46 ValidateFunc func(*terraform.ResourceConfig) ([]string, []error)
47 47
48 stopCtx context.Context 48 stopCtx context.Context
49 stopCtxCancel context.CancelFunc 49 stopCtxCancel context.CancelFunc
@@ -121,32 +121,6 @@ func (p *Provisioner) Stop() error {
121 return nil 121 return nil
122} 122}
123 123
124func (p *Provisioner) Validate(config *terraform.ResourceConfig) ([]string, []error) {
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
148}
149
150// Apply implementation of terraform.ResourceProvisioner interface. 124// Apply implementation of terraform.ResourceProvisioner interface.
151func (p *Provisioner) Apply( 125func (p *Provisioner) Apply(
152 o terraform.UIOutput, 126 o terraform.UIOutput,
@@ -204,3 +178,27 @@ func (p *Provisioner) Apply(
204 ctx = context.WithValue(ctx, ProvRawStateKey, s) 178 ctx = context.WithValue(ctx, ProvRawStateKey, s)
205 return p.ApplyFunc(ctx) 179 return p.ApplyFunc(ctx)
206} 180}
181
182// Validate implements the terraform.ResourceProvisioner interface.
183func (p *Provisioner) Validate(c *terraform.ResourceConfig) (ws []string, es []error) {
184 if err := p.InternalValidate(); err != nil {
185 return nil, []error{fmt.Errorf(
186 "Internal validation of the provisioner failed! This is always a bug\n"+
187 "with the provisioner itself, and not a user issue. Please report\n"+
188 "this bug:\n\n%s", err)}
189 }
190
191 if p.Schema != nil {
192 w, e := schemaMap(p.Schema).Validate(c)
193 ws = append(ws, w...)
194 es = append(es, e...)
195 }
196
197 if p.ValidateFunc != nil {
198 w, e := p.ValidateFunc(c)
199 ws = append(ws, w...)
200 es = append(es, e...)
201 }
202
203 return ws, es
204}
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/resource.go b/vendor/github.com/hashicorp/terraform/helper/schema/resource.go
index c810558..ddba109 100644
--- a/vendor/github.com/hashicorp/terraform/helper/schema/resource.go
+++ b/vendor/github.com/hashicorp/terraform/helper/schema/resource.go
@@ -6,6 +6,7 @@ import (
6 "log" 6 "log"
7 "strconv" 7 "strconv"
8 8
9 "github.com/hashicorp/terraform/config"
9 "github.com/hashicorp/terraform/terraform" 10 "github.com/hashicorp/terraform/terraform"
10) 11)
11 12
@@ -142,6 +143,12 @@ func (r *Resource) Apply(
142 if err := rt.DiffDecode(d); err != nil { 143 if err := rt.DiffDecode(d); err != nil {
143 log.Printf("[ERR] Error decoding ResourceTimeout: %s", err) 144 log.Printf("[ERR] Error decoding ResourceTimeout: %s", err)
144 } 145 }
146 } else if s != nil {
147 if _, ok := s.Meta[TimeoutKey]; ok {
148 if err := rt.StateDecode(s); err != nil {
149 log.Printf("[ERR] Error decoding ResourceTimeout: %s", err)
150 }
151 }
145 } else { 152 } else {
146 log.Printf("[DEBUG] No meta timeoutkey found in Apply()") 153 log.Printf("[DEBUG] No meta timeoutkey found in Apply()")
147 } 154 }
@@ -388,9 +395,25 @@ func (r *Resource) InternalValidate(topSchemaMap schemaMap, writable bool) error
388 } 395 }
389 } 396 }
390 397
398 // Resource-specific checks
399 for k, _ := range tsm {
400 if isReservedResourceFieldName(k) {
401 return fmt.Errorf("%s is a reserved field name for a resource", k)
402 }
403 }
404
391 return schemaMap(r.Schema).InternalValidate(tsm) 405 return schemaMap(r.Schema).InternalValidate(tsm)
392} 406}
393 407
408func isReservedResourceFieldName(name string) bool {
409 for _, reservedName := range config.ReservedResourceFields {
410 if name == reservedName {
411 return true
412 }
413 }
414 return false
415}
416
394// Data returns a ResourceData struct for this Resource. Each return value 417// Data returns a ResourceData struct for this Resource. Each return value
395// is a separate copy and can be safely modified differently. 418// is a separate copy and can be safely modified differently.
396// 419//
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/schema.go b/vendor/github.com/hashicorp/terraform/helper/schema/schema.go
index 632672a..acb5618 100644
--- a/vendor/github.com/hashicorp/terraform/helper/schema/schema.go
+++ b/vendor/github.com/hashicorp/terraform/helper/schema/schema.go
@@ -15,6 +15,7 @@ import (
15 "fmt" 15 "fmt"
16 "os" 16 "os"
17 "reflect" 17 "reflect"
18 "regexp"
18 "sort" 19 "sort"
19 "strconv" 20 "strconv"
20 "strings" 21 "strings"
@@ -661,7 +662,13 @@ func (m schemaMap) InternalValidate(topSchemaMap schemaMap) error {
661 if v.ValidateFunc != nil { 662 if v.ValidateFunc != nil {
662 switch v.Type { 663 switch v.Type {
663 case TypeList, TypeSet: 664 case TypeList, TypeSet:
664 return fmt.Errorf("ValidateFunc is not yet supported on lists or sets.") 665 return fmt.Errorf("%s: ValidateFunc is not yet supported on lists or sets.", k)
666 }
667 }
668
669 if v.Deprecated == "" && v.Removed == "" {
670 if !isValidFieldName(k) {
671 return fmt.Errorf("%s: Field name may only contain lowercase alphanumeric characters & underscores.", k)
665 } 672 }
666 } 673 }
667 } 674 }
@@ -669,6 +676,11 @@ func (m schemaMap) InternalValidate(topSchemaMap schemaMap) error {
669 return nil 676 return nil
670} 677}
671 678
679func isValidFieldName(name string) bool {
680 re := regexp.MustCompile("^[a-z0-9_]+$")
681 return re.MatchString(name)
682}
683
672func (m schemaMap) diff( 684func (m schemaMap) diff(
673 k string, 685 k string,
674 schema *Schema, 686 schema *Schema,
diff --git a/vendor/github.com/hashicorp/terraform/helper/shadow/closer.go b/vendor/github.com/hashicorp/terraform/helper/shadow/closer.go
index 7edd5e7..edc1e2a 100644
--- a/vendor/github.com/hashicorp/terraform/helper/shadow/closer.go
+++ b/vendor/github.com/hashicorp/terraform/helper/shadow/closer.go
@@ -39,6 +39,8 @@ func (w *closeWalker) Struct(reflect.Value) error {
39 return nil 39 return nil
40} 40}
41 41
42var closerType = reflect.TypeOf((*io.Closer)(nil)).Elem()
43
42func (w *closeWalker) StructField(f reflect.StructField, v reflect.Value) error { 44func (w *closeWalker) StructField(f reflect.StructField, v reflect.Value) error {
43 // Not sure why this would be but lets avoid some panics 45 // Not sure why this would be but lets avoid some panics
44 if !v.IsValid() { 46 if !v.IsValid() {
@@ -56,17 +58,18 @@ func (w *closeWalker) StructField(f reflect.StructField, v reflect.Value) error
56 return nil 58 return nil
57 } 59 }
58 60
59 // We're looking for an io.Closer 61 var closer io.Closer
60 raw := v.Interface() 62 if v.Type().Implements(closerType) {
61 if raw == nil { 63 closer = v.Interface().(io.Closer)
62 return nil 64 } else if v.CanAddr() {
65 // The Close method may require a pointer receiver, but we only have a value.
66 v := v.Addr()
67 if v.Type().Implements(closerType) {
68 closer = v.Interface().(io.Closer)
69 }
63 } 70 }
64 71
65 closer, ok := raw.(io.Closer) 72 if closer == nil {
66 if !ok && v.CanAddr() {
67 closer, ok = v.Addr().Interface().(io.Closer)
68 }
69 if !ok {
70 return reflectwalk.SkipEntry 73 return reflectwalk.SkipEntry
71 } 74 }
72 75
diff --git a/vendor/github.com/hashicorp/terraform/helper/shadow/value.go b/vendor/github.com/hashicorp/terraform/helper/shadow/value.go
index 2413335..178b7e7 100644
--- a/vendor/github.com/hashicorp/terraform/helper/shadow/value.go
+++ b/vendor/github.com/hashicorp/terraform/helper/shadow/value.go
@@ -26,6 +26,14 @@ type Value struct {
26 valueSet bool 26 valueSet bool
27} 27}
28 28
29func (v *Value) Lock() {
30 v.lock.Lock()
31}
32
33func (v *Value) Unlock() {
34 v.lock.Unlock()
35}
36
29// Close closes the value. This can never fail. For a definition of 37// Close closes the value. This can never fail. For a definition of
30// "close" see the struct docs. 38// "close" see the struct docs.
31func (w *Value) Close() error { 39func (w *Value) Close() error {
diff --git a/vendor/github.com/hashicorp/terraform/moduledeps/dependencies.go b/vendor/github.com/hashicorp/terraform/moduledeps/dependencies.go
new file mode 100644
index 0000000..87c8431
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/moduledeps/dependencies.go
@@ -0,0 +1,43 @@
1package moduledeps
2
3import (
4 "github.com/hashicorp/terraform/plugin/discovery"
5)
6
7// Providers describes a set of provider dependencies for a given module.
8//
9// Each named provider instance can have one version constraint.
10type Providers map[ProviderInstance]ProviderDependency
11
12// ProviderDependency describes the dependency for a particular provider
13// instance, including both the set of allowed versions and the reason for
14// the dependency.
15type ProviderDependency struct {
16 Constraints discovery.Constraints
17 Reason ProviderDependencyReason
18}
19
20// ProviderDependencyReason is an enumeration of reasons why a dependency might be
21// present.
22type ProviderDependencyReason int
23
24const (
25 // ProviderDependencyExplicit means that there is an explicit "provider"
26 // block in the configuration for this module.
27 ProviderDependencyExplicit ProviderDependencyReason = iota
28
29 // ProviderDependencyImplicit means that there is no explicit "provider"
30 // block but there is at least one resource that uses this provider.
31 ProviderDependencyImplicit
32
33 // ProviderDependencyInherited is a special case of
34 // ProviderDependencyImplicit where a parent module has defined a
35 // configuration for the provider that has been inherited by at least one
36 // resource in this module.
37 ProviderDependencyInherited
38
39 // ProviderDependencyFromState means that this provider is not currently
40 // referenced by configuration at all, but some existing instances in
41 // the state still depend on it.
42 ProviderDependencyFromState
43)
diff --git a/vendor/github.com/hashicorp/terraform/moduledeps/doc.go b/vendor/github.com/hashicorp/terraform/moduledeps/doc.go
new file mode 100644
index 0000000..7eff083
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/moduledeps/doc.go
@@ -0,0 +1,7 @@
1// Package moduledeps contains types that can be used to describe the
2// providers required for all of the modules in a module tree.
3//
4// It does not itself contain the functionality for populating such
5// data structures; that's in Terraform core, since this package intentionally
6// does not depend on terraform core to avoid package dependency cycles.
7package moduledeps
diff --git a/vendor/github.com/hashicorp/terraform/moduledeps/module.go b/vendor/github.com/hashicorp/terraform/moduledeps/module.go
new file mode 100644
index 0000000..d6cbaf5
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/moduledeps/module.go
@@ -0,0 +1,204 @@
1package moduledeps
2
3import (
4 "sort"
5 "strings"
6
7 "github.com/hashicorp/terraform/plugin/discovery"
8)
9
10// Module represents the dependencies of a single module, as well being
11// a node in a tree of such structures representing the dependencies of
12// an entire configuration.
13type Module struct {
14 Name string
15 Providers Providers
16 Children []*Module
17}
18
19// WalkFunc is a callback type for use with Module.WalkTree
20type WalkFunc func(path []string, parent *Module, current *Module) error
21
22// WalkTree calls the given callback once for the receiver and then
23// once for each descendent, in an order such that parents are called
24// before their children and siblings are called in the order they
25// appear in the Children slice.
26//
27// When calling the callback, parent will be nil for the first call
28// for the receiving module, and then set to the direct parent of
29// each module for the subsequent calls.
30//
31// The path given to the callback is valid only until the callback
32// returns, after which it will be mutated and reused. Callbacks must
33// therefore copy the path slice if they wish to retain it.
34//
35// If the given callback returns an error, the walk will be aborted at
36// that point and that error returned to the caller.
37//
38// This function is not thread-safe for concurrent modifications of the
39// data structure, so it's the caller's responsibility to arrange for that
40// should it be needed.
41//
42// It is safe for a callback to modify the descendents of the "current"
43// module, including the ordering of the Children slice itself, but the
44// callback MUST NOT modify the parent module.
45func (m *Module) WalkTree(cb WalkFunc) error {
46 return walkModuleTree(make([]string, 0, 1), nil, m, cb)
47}
48
49func walkModuleTree(path []string, parent *Module, current *Module, cb WalkFunc) error {
50 path = append(path, current.Name)
51 err := cb(path, parent, current)
52 if err != nil {
53 return err
54 }
55
56 for _, child := range current.Children {
57 err := walkModuleTree(path, current, child, cb)
58 if err != nil {
59 return err
60 }
61 }
62 return nil
63}
64
65// SortChildren sorts the Children slice into lexicographic order by
66// name, in-place.
67//
68// This is primarily useful prior to calling WalkTree so that the walk
69// will proceed in a consistent order.
70func (m *Module) SortChildren() {
71 sort.Sort(sortModules{m.Children})
72}
73
74// SortDescendents is a convenience wrapper for calling SortChildren on
75// the receiver and all of its descendent modules.
76func (m *Module) SortDescendents() {
77 m.WalkTree(func(path []string, parent *Module, current *Module) error {
78 current.SortChildren()
79 return nil
80 })
81}
82
83type sortModules struct {
84 modules []*Module
85}
86
87func (s sortModules) Len() int {
88 return len(s.modules)
89}
90
91func (s sortModules) Less(i, j int) bool {
92 cmp := strings.Compare(s.modules[i].Name, s.modules[j].Name)
93 return cmp < 0
94}
95
96func (s sortModules) Swap(i, j int) {
97 s.modules[i], s.modules[j] = s.modules[j], s.modules[i]
98}
99
100// PluginRequirements produces a PluginRequirements structure that can
101// be used with discovery.PluginMetaSet.ConstrainVersions to identify
102// suitable plugins to satisfy the module's provider dependencies.
103//
104// This method only considers the direct requirements of the receiver.
105// Use AllPluginRequirements to flatten the dependencies for the
106// entire tree of modules.
107//
108// Requirements returned by this method include only version constraints,
109// and apply no particular SHA256 hash constraint.
110func (m *Module) PluginRequirements() discovery.PluginRequirements {
111 ret := make(discovery.PluginRequirements)
112 for inst, dep := range m.Providers {
113 // m.Providers is keyed on provider names, such as "aws.foo".
114 // a PluginRequirements wants keys to be provider *types*, such
115 // as "aws". If there are multiple aliases for the same
116 // provider then we will flatten them into a single requirement
117 // by combining their constraint sets.
118 pty := inst.Type()
119 if existing, exists := ret[pty]; exists {
120 ret[pty].Versions = existing.Versions.Append(dep.Constraints)
121 } else {
122 ret[pty] = &discovery.PluginConstraints{
123 Versions: dep.Constraints,
124 }
125 }
126 }
127 return ret
128}
129
130// AllPluginRequirements calls PluginRequirements for the receiver and all
131// of its descendents, and merges the result into a single PluginRequirements
132// structure that would satisfy all of the modules together.
133//
134// Requirements returned by this method include only version constraints,
135// and apply no particular SHA256 hash constraint.
136func (m *Module) AllPluginRequirements() discovery.PluginRequirements {
137 var ret discovery.PluginRequirements
138 m.WalkTree(func(path []string, parent *Module, current *Module) error {
139 ret = ret.Merge(current.PluginRequirements())
140 return nil
141 })
142 return ret
143}
144
145// Equal returns true if the receiver is the root of an identical tree
146// to the other given Module. This is a deep comparison that considers
147// the equality of all downstream modules too.
148//
149// The children are considered to be ordered, so callers may wish to use
150// SortDescendents first to normalize the order of the slices of child nodes.
151//
152// The implementation of this function is not optimized since it is provided
153// primarily for use in tests.
154func (m *Module) Equal(other *Module) bool {
155 // take care of nils first
156 if m == nil && other == nil {
157 return true
158 } else if (m == nil && other != nil) || (m != nil && other == nil) {
159 return false
160 }
161
162 if m.Name != other.Name {
163 return false
164 }
165
166 if len(m.Providers) != len(other.Providers) {
167 return false
168 }
169 if len(m.Children) != len(other.Children) {
170 return false
171 }
172
173 // Can't use reflect.DeepEqual on this provider structure because
174 // the nested Constraints objects contain function pointers that
175 // never compare as equal. So we'll need to walk it the long way.
176 for inst, dep := range m.Providers {
177 if _, exists := other.Providers[inst]; !exists {
178 return false
179 }
180
181 if dep.Reason != other.Providers[inst].Reason {
182 return false
183 }
184
185 // Constraints are not too easy to compare robustly, so
186 // we'll just use their string representations as a proxy
187 // for now.
188 if dep.Constraints.String() != other.Providers[inst].Constraints.String() {
189 return false
190 }
191 }
192
193 // Above we already checked that we have the same number of children
194 // in each module, so now we just need to check that they are
195 // recursively equal.
196 for i := range m.Children {
197 if !m.Children[i].Equal(other.Children[i]) {
198 return false
199 }
200 }
201
202 // If we fall out here then they are equal
203 return true
204}
diff --git a/vendor/github.com/hashicorp/terraform/moduledeps/provider.go b/vendor/github.com/hashicorp/terraform/moduledeps/provider.go
new file mode 100644
index 0000000..89ceefb
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/moduledeps/provider.go
@@ -0,0 +1,30 @@
1package moduledeps
2
3import (
4 "strings"
5)
6
7// ProviderInstance describes a particular provider instance by its full name,
8// like "null" or "aws.foo".
9type ProviderInstance string
10
11// Type returns the provider type of this instance. For example, for an instance
12// named "aws.foo" the type is "aws".
13func (p ProviderInstance) Type() string {
14 t := string(p)
15 if dotPos := strings.Index(t, "."); dotPos != -1 {
16 t = t[:dotPos]
17 }
18 return t
19}
20
21// Alias returns the alias of this provider, if any. An instance named "aws.foo"
22// has the alias "foo", while an instance named just "docker" has no alias,
23// so the empty string would be returned.
24func (p ProviderInstance) Alias() string {
25 t := string(p)
26 if dotPos := strings.Index(t, "."); dotPos != -1 {
27 return t[dotPos+1:]
28 }
29 return ""
30}
diff --git a/vendor/github.com/hashicorp/terraform/plugin/client.go b/vendor/github.com/hashicorp/terraform/plugin/client.go
new file mode 100644
index 0000000..3a5cb7a
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/plugin/client.go
@@ -0,0 +1,24 @@
1package plugin
2
3import (
4 "os/exec"
5
6 plugin "github.com/hashicorp/go-plugin"
7 "github.com/hashicorp/terraform/plugin/discovery"
8)
9
10// ClientConfig returns a configuration object that can be used to instantiate
11// a client for the plugin described by the given metadata.
12func ClientConfig(m discovery.PluginMeta) *plugin.ClientConfig {
13 return &plugin.ClientConfig{
14 Cmd: exec.Command(m.Path),
15 HandshakeConfig: Handshake,
16 Managed: true,
17 Plugins: PluginMap,
18 }
19}
20
21// Client returns a plugin client for the plugin described by the given metadata.
22func Client(m discovery.PluginMeta) *plugin.Client {
23 return plugin.NewClient(ClientConfig(m))
24}
diff --git a/vendor/github.com/hashicorp/terraform/plugin/discovery/error.go b/vendor/github.com/hashicorp/terraform/plugin/discovery/error.go
new file mode 100644
index 0000000..df855a7
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/plugin/discovery/error.go
@@ -0,0 +1,30 @@
1package discovery
2
3// Error is a type used to describe situations that the caller must handle
4// since they indicate some form of user error.
5//
6// The functions and methods that return these specialized errors indicate so
7// in their documentation. The Error type should not itself be used directly,
8// but rather errors should be compared using the == operator with the
9// error constants in this package.
10//
11// Values of this type are _not_ used when the error being reported is an
12// operational error (server unavailable, etc) or indicative of a bug in
13// this package or its caller.
14type Error string
15
16// ErrorNoSuitableVersion indicates that a suitable version (meeting given
17// constraints) is not available.
18const ErrorNoSuitableVersion = Error("no suitable version is available")
19
20// ErrorNoVersionCompatible indicates that all of the available versions
21// that otherwise met constraints are not compatible with the current
22// version of Terraform.
23const ErrorNoVersionCompatible = Error("no available version is compatible with this version of Terraform")
24
25// ErrorNoSuchProvider indicates that no provider exists with a name given
26const ErrorNoSuchProvider = Error("no provider exists with the given name")
27
28func (err Error) Error() string {
29 return string(err)
30}
diff --git a/vendor/github.com/hashicorp/terraform/plugin/discovery/find.go b/vendor/github.com/hashicorp/terraform/plugin/discovery/find.go
new file mode 100644
index 0000000..f5bc4c1
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/plugin/discovery/find.go
@@ -0,0 +1,168 @@
1package discovery
2
3import (
4 "io/ioutil"
5 "log"
6 "path/filepath"
7 "strings"
8)
9
10// FindPlugins looks in the given directories for files whose filenames
11// suggest that they are plugins of the given kind (e.g. "provider") and
12// returns a PluginMetaSet representing the discovered potential-plugins.
13//
14// Currently this supports two different naming schemes. The current
15// standard naming scheme is a subdirectory called $GOOS-$GOARCH containing
16// files named terraform-$KIND-$NAME-V$VERSION. The legacy naming scheme is
17// files directly in the given directory whose names are like
18// terraform-$KIND-$NAME.
19//
20// Only one plugin will be returned for each unique plugin (name, version)
21// pair, with preference given to files found in earlier directories.
22//
23// This is a convenience wrapper around FindPluginPaths and ResolvePluginsPaths.
24func FindPlugins(kind string, dirs []string) PluginMetaSet {
25 return ResolvePluginPaths(FindPluginPaths(kind, dirs))
26}
27
28// FindPluginPaths looks in the given directories for files whose filenames
29// suggest that they are plugins of the given kind (e.g. "provider").
30//
31// The return value is a list of absolute paths that appear to refer to
32// plugins in the given directories, based only on what can be inferred
33// from the naming scheme. The paths returned are ordered such that files
34// in later dirs appear after files in earlier dirs in the given directory
35// list. Within the same directory plugins are returned in a consistent but
36// undefined order.
37func FindPluginPaths(kind string, dirs []string) []string {
38 // This is just a thin wrapper around findPluginPaths so that we can
39 // use the latter in tests with a fake machineName so we can use our
40 // test fixtures.
41 return findPluginPaths(kind, dirs)
42}
43
44func findPluginPaths(kind string, dirs []string) []string {
45 prefix := "terraform-" + kind + "-"
46
47 ret := make([]string, 0, len(dirs))
48
49 for _, dir := range dirs {
50 items, err := ioutil.ReadDir(dir)
51 if err != nil {
52 // Ignore missing dirs, non-dirs, etc
53 continue
54 }
55
56 log.Printf("[DEBUG] checking for %s in %q", kind, dir)
57
58 for _, item := range items {
59 fullName := item.Name()
60
61 if !strings.HasPrefix(fullName, prefix) {
62 log.Printf("[DEBUG] skipping %q, not a %s", fullName, kind)
63 continue
64 }
65
66 // New-style paths must have a version segment in filename
67 if strings.Contains(strings.ToLower(fullName), "_v") {
68 absPath, err := filepath.Abs(filepath.Join(dir, fullName))
69 if err != nil {
70 log.Printf("[ERROR] plugin filepath error: %s", err)
71 continue
72 }
73
74 log.Printf("[DEBUG] found %s %q", kind, fullName)
75 ret = append(ret, filepath.Clean(absPath))
76 continue
77 }
78
79 // Legacy style with files directly in the base directory
80 absPath, err := filepath.Abs(filepath.Join(dir, fullName))
81 if err != nil {
82 log.Printf("[ERROR] plugin filepath error: %s", err)
83 continue
84 }
85
86 log.Printf("[WARNING] found legacy %s %q", kind, fullName)
87
88 ret = append(ret, filepath.Clean(absPath))
89 }
90 }
91
92 return ret
93}
94
95// ResolvePluginPaths takes a list of paths to plugin executables (as returned
96// by e.g. FindPluginPaths) and produces a PluginMetaSet describing the
97// referenced plugins.
98//
99// If the same combination of plugin name and version appears multiple times,
100// the earlier reference will be preferred. Several different versions of
101// the same plugin name may be returned, in which case the methods of
102// PluginMetaSet can be used to filter down.
103func ResolvePluginPaths(paths []string) PluginMetaSet {
104 s := make(PluginMetaSet)
105
106 type nameVersion struct {
107 Name string
108 Version string
109 }
110 found := make(map[nameVersion]struct{})
111
112 for _, path := range paths {
113 baseName := strings.ToLower(filepath.Base(path))
114 if !strings.HasPrefix(baseName, "terraform-") {
115 // Should never happen with reasonable input
116 continue
117 }
118
119 baseName = baseName[10:]
120 firstDash := strings.Index(baseName, "-")
121 if firstDash == -1 {
122 // Should never happen with reasonable input
123 continue
124 }
125
126 baseName = baseName[firstDash+1:]
127 if baseName == "" {
128 // Should never happen with reasonable input
129 continue
130 }
131
132 // Trim the .exe suffix used on Windows before we start wrangling
133 // the remainder of the path.
134 if strings.HasSuffix(baseName, ".exe") {
135 baseName = baseName[:len(baseName)-4]
136 }
137
138 parts := strings.SplitN(baseName, "_v", 2)
139 name := parts[0]
140 version := VersionZero
141 if len(parts) == 2 {
142 version = parts[1]
143 }
144
145 // Auto-installed plugins contain an extra name portion representing
146 // the expected plugin version, which we must trim off.
147 if underX := strings.Index(version, "_x"); underX != -1 {
148 version = version[:underX]
149 }
150
151 if _, ok := found[nameVersion{name, version}]; ok {
152 // Skip duplicate versions of the same plugin
153 // (We do this during this step because after this we will be
154 // dealing with sets and thus lose our ordering with which to
155 // decide preference.)
156 continue
157 }
158
159 s.Add(PluginMeta{
160 Name: name,
161 Version: VersionStr(version),
162 Path: path,
163 })
164 found[nameVersion{name, version}] = struct{}{}
165 }
166
167 return s
168}
diff --git a/vendor/github.com/hashicorp/terraform/plugin/discovery/get.go b/vendor/github.com/hashicorp/terraform/plugin/discovery/get.go
new file mode 100644
index 0000000..241b5cb
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/plugin/discovery/get.go
@@ -0,0 +1,424 @@
1package discovery
2
3import (
4 "errors"
5 "fmt"
6 "io/ioutil"
7 "log"
8 "net/http"
9 "os"
10 "runtime"
11 "strconv"
12 "strings"
13
14 "golang.org/x/net/html"
15
16 cleanhttp "github.com/hashicorp/go-cleanhttp"
17 getter "github.com/hashicorp/go-getter"
18 multierror "github.com/hashicorp/go-multierror"
19)
20
21// Releases are located by parsing the html listing from releases.hashicorp.com.
22//
23// The URL for releases follows the pattern:
24// https://releases.hashicorp.com/terraform-provider-name/<x.y.z>/terraform-provider-name_<x.y.z>_<os>_<arch>.<ext>
25//
26// The plugin protocol version will be saved with the release and returned in
27// the header X-TERRAFORM_PROTOCOL_VERSION.
28
29const protocolVersionHeader = "x-terraform-protocol-version"
30
31var releaseHost = "https://releases.hashicorp.com"
32
33var httpClient = cleanhttp.DefaultClient()
34
35// An Installer maintains a local cache of plugins by downloading plugins
36// from an online repository.
37type Installer interface {
38 Get(name string, req Constraints) (PluginMeta, error)
39 PurgeUnused(used map[string]PluginMeta) (removed PluginMetaSet, err error)
40}
41
42// ProviderInstaller is an Installer implementation that knows how to
43// download Terraform providers from the official HashiCorp releases service
44// into a local directory. The files downloaded are compliant with the
45// naming scheme expected by FindPlugins, so the target directory of a
46// provider installer can be used as one of several plugin discovery sources.
47type ProviderInstaller struct {
48 Dir string
49
50 PluginProtocolVersion uint
51
52 // OS and Arch specify the OS and architecture that should be used when
53 // installing plugins. These use the same labels as the runtime.GOOS and
54 // runtime.GOARCH variables respectively, and indeed the values of these
55 // are used as defaults if either of these is the empty string.
56 OS string
57 Arch string
58
59 // Skip checksum and signature verification
60 SkipVerify bool
61}
62
63// Get is part of an implementation of type Installer, and attempts to download
64// and install a Terraform provider matching the given constraints.
65//
66// This method may return one of a number of sentinel errors from this
67// package to indicate issues that are likely to be resolvable via user action:
68//
69// ErrorNoSuchProvider: no provider with the given name exists in the repository.
70// ErrorNoSuitableVersion: the provider exists but no available version matches constraints.
71// ErrorNoVersionCompatible: a plugin was found within the constraints but it is
72// incompatible with the current Terraform version.
73//
74// These errors should be recognized and handled as special cases by the caller
75// to present a suitable user-oriented error message.
76//
77// All other errors indicate an internal problem that is likely _not_ solvable
78// through user action, or at least not within Terraform's scope. Error messages
79// are produced under the assumption that if presented to the user they will
80// be presented alongside context about what is being installed, and thus the
81// error messages do not redundantly include such information.
82func (i *ProviderInstaller) Get(provider string, req Constraints) (PluginMeta, error) {
83 versions, err := i.listProviderVersions(provider)
84 // TODO: return multiple errors
85 if err != nil {
86 return PluginMeta{}, err
87 }
88
89 if len(versions) == 0 {
90 return PluginMeta{}, ErrorNoSuitableVersion
91 }
92
93 versions = allowedVersions(versions, req)
94 if len(versions) == 0 {
95 return PluginMeta{}, ErrorNoSuitableVersion
96 }
97
98 // sort them newest to oldest
99 Versions(versions).Sort()
100
101 // take the first matching plugin we find
102 for _, v := range versions {
103 url := i.providerURL(provider, v.String())
104
105 if !i.SkipVerify {
106 sha256, err := i.getProviderChecksum(provider, v.String())
107 if err != nil {
108 return PluginMeta{}, err
109 }
110
111 // add the checksum parameter for go-getter to verify the download for us.
112 if sha256 != "" {
113 url = url + "?checksum=sha256:" + sha256
114 }
115 }
116
117 log.Printf("[DEBUG] fetching provider info for %s version %s", provider, v)
118 if checkPlugin(url, i.PluginProtocolVersion) {
119 log.Printf("[DEBUG] getting provider %q version %q at %s", provider, v, url)
120 err := getter.Get(i.Dir, url)
121 if err != nil {
122 return PluginMeta{}, err
123 }
124
125 // Find what we just installed
126 // (This is weird, because go-getter doesn't directly return
127 // information about what was extracted, and we just extracted
128 // the archive directly into a shared dir here.)
129 log.Printf("[DEBUG] looking for the %s %s plugin we just installed", provider, v)
130 metas := FindPlugins("provider", []string{i.Dir})
131 log.Printf("[DEBUG] all plugins found %#v", metas)
132 metas, _ = metas.ValidateVersions()
133 metas = metas.WithName(provider).WithVersion(v)
134 log.Printf("[DEBUG] filtered plugins %#v", metas)
135 if metas.Count() == 0 {
136 // This should never happen. Suggests that the release archive
137 // contains an executable file whose name doesn't match the
138 // expected convention.
139 return PluginMeta{}, fmt.Errorf(
140 "failed to find installed plugin version %s; this is a bug in Terraform and should be reported",
141 v,
142 )
143 }
144
145 if metas.Count() > 1 {
146 // This should also never happen, and suggests that a
147 // particular version was re-released with a different
148 // executable filename. We consider releases as immutable, so
149 // this is an error.
150 return PluginMeta{}, fmt.Errorf(
151 "multiple plugins installed for version %s; this is a bug in Terraform and should be reported",
152 v,
153 )
154 }
155
156 // By now we know we have exactly one meta, and so "Newest" will
157 // return that one.
158 return metas.Newest(), nil
159 }
160
161 log.Printf("[INFO] incompatible ProtocolVersion for %s version %s", provider, v)
162 }
163
164 return PluginMeta{}, ErrorNoVersionCompatible
165}
166
167func (i *ProviderInstaller) PurgeUnused(used map[string]PluginMeta) (PluginMetaSet, error) {
168 purge := make(PluginMetaSet)
169
170 present := FindPlugins("provider", []string{i.Dir})
171 for meta := range present {
172 chosen, ok := used[meta.Name]
173 if !ok {
174 purge.Add(meta)
175 }
176 if chosen.Path != meta.Path {
177 purge.Add(meta)
178 }
179 }
180
181 removed := make(PluginMetaSet)
182 var errs error
183 for meta := range purge {
184 path := meta.Path
185 err := os.Remove(path)
186 if err != nil {
187 errs = multierror.Append(errs, fmt.Errorf(
188 "failed to remove unused provider plugin %s: %s",
189 path, err,
190 ))
191 } else {
192 removed.Add(meta)
193 }
194 }
195
196 return removed, errs
197}
198
199// Plugins are referred to by the short name, but all URLs and files will use
200// the full name prefixed with terraform-<plugin_type>-
201func (i *ProviderInstaller) providerName(name string) string {
202 return "terraform-provider-" + name
203}
204
205func (i *ProviderInstaller) providerFileName(name, version string) string {
206 os := i.OS
207 arch := i.Arch
208 if os == "" {
209 os = runtime.GOOS
210 }
211 if arch == "" {
212 arch = runtime.GOARCH
213 }
214 return fmt.Sprintf("%s_%s_%s_%s.zip", i.providerName(name), version, os, arch)
215}
216
217// providerVersionsURL returns the path to the released versions directory for the provider:
218// https://releases.hashicorp.com/terraform-provider-name/
219func (i *ProviderInstaller) providerVersionsURL(name string) string {
220 return releaseHost + "/" + i.providerName(name) + "/"
221}
222
223// providerURL returns the full path to the provider file, using the current OS
224// and ARCH:
225// .../terraform-provider-name_<x.y.z>/terraform-provider-name_<x.y.z>_<os>_<arch>.<ext>
226func (i *ProviderInstaller) providerURL(name, version string) string {
227 return fmt.Sprintf("%s%s/%s", i.providerVersionsURL(name), version, i.providerFileName(name, version))
228}
229
230func (i *ProviderInstaller) providerChecksumURL(name, version string) string {
231 fileName := fmt.Sprintf("%s_%s_SHA256SUMS", i.providerName(name), version)
232 u := fmt.Sprintf("%s%s/%s", i.providerVersionsURL(name), version, fileName)
233 return u
234}
235
236func (i *ProviderInstaller) getProviderChecksum(name, version string) (string, error) {
237 checksums, err := getPluginSHA256SUMs(i.providerChecksumURL(name, version))
238 if err != nil {
239 return "", err
240 }
241
242 return checksumForFile(checksums, i.providerFileName(name, version)), nil
243}
244
245// Return the plugin version by making a HEAD request to the provided url.
246// If the header is not present, we assume the latest version will be
247// compatible, and leave the check for discovery or execution.
248func checkPlugin(url string, pluginProtocolVersion uint) bool {
249 resp, err := httpClient.Head(url)
250 if err != nil {
251 log.Printf("[ERROR] error fetching plugin headers: %s", err)
252 return false
253 }
254
255 if resp.StatusCode != http.StatusOK {
256 log.Println("[ERROR] non-200 status fetching plugin headers:", resp.Status)
257 return false
258 }
259
260 proto := resp.Header.Get(protocolVersionHeader)
261 if proto == "" {
262 // The header isn't present, but we don't make this error fatal since
263 // the latest version will probably work.
264 log.Printf("[WARNING] missing %s from: %s", protocolVersionHeader, url)
265 return true
266 }
267
268 protoVersion, err := strconv.Atoi(proto)
269 if err != nil {
270 log.Printf("[ERROR] invalid ProtocolVersion: %s", proto)
271 return false
272 }
273
274 return protoVersion == int(pluginProtocolVersion)
275}
276
277// list the version available for the named plugin
278func (i *ProviderInstaller) listProviderVersions(name string) ([]Version, error) {
279 versions, err := listPluginVersions(i.providerVersionsURL(name))
280 if err != nil {
281 // listPluginVersions returns a verbose error message indicating
282 // what was being accessed and what failed
283 return nil, err
284 }
285 return versions, nil
286}
287
288var errVersionNotFound = errors.New("version not found")
289
290// take the list of available versions for a plugin, and filter out those that
291// don't fit the constraints.
292func allowedVersions(available []Version, required Constraints) []Version {
293 var allowed []Version
294
295 for _, v := range available {
296 if required.Allows(v) {
297 allowed = append(allowed, v)
298 }
299 }
300
301 return allowed
302}
303
304// return a list of the plugin versions at the given URL
305func listPluginVersions(url string) ([]Version, error) {
306 resp, err := httpClient.Get(url)
307 if err != nil {
308 // http library produces a verbose error message that includes the
309 // URL being accessed, etc.
310 return nil, err
311 }
312 defer resp.Body.Close()
313
314 if resp.StatusCode != http.StatusOK {
315 body, _ := ioutil.ReadAll(resp.Body)
316 log.Printf("[ERROR] failed to fetch plugin versions from %s\n%s\n%s", url, resp.Status, body)
317
318 switch resp.StatusCode {
319 case http.StatusNotFound, http.StatusForbidden:
320 // These are treated as indicative of the given name not being
321 // a valid provider name at all.
322 return nil, ErrorNoSuchProvider
323
324 default:
325 // All other errors are assumed to be operational problems.
326 return nil, fmt.Errorf("error accessing %s: %s", url, resp.Status)
327 }
328
329 }
330
331 body, err := html.Parse(resp.Body)
332 if err != nil {
333 log.Fatal(err)
334 }
335
336 names := []string{}
337
338 // all we need to do is list links on the directory listing page that look like plugins
339 var f func(*html.Node)
340 f = func(n *html.Node) {
341 if n.Type == html.ElementNode && n.Data == "a" {
342 c := n.FirstChild
343 if c != nil && c.Type == html.TextNode && strings.HasPrefix(c.Data, "terraform-") {
344 names = append(names, c.Data)
345 return
346 }
347 }
348 for c := n.FirstChild; c != nil; c = c.NextSibling {
349 f(c)
350 }
351 }
352 f(body)
353
354 return versionsFromNames(names), nil
355}
356
357// parse the list of directory names into a sorted list of available versions
358func versionsFromNames(names []string) []Version {
359 var versions []Version
360 for _, name := range names {
361 parts := strings.SplitN(name, "_", 2)
362 if len(parts) == 2 && parts[1] != "" {
363 v, err := VersionStr(parts[1]).Parse()
364 if err != nil {
365 // filter invalid versions scraped from the page
366 log.Printf("[WARN] invalid version found for %q: %s", name, err)
367 continue
368 }
369
370 versions = append(versions, v)
371 }
372 }
373
374 return versions
375}
376
377func checksumForFile(sums []byte, name string) string {
378 for _, line := range strings.Split(string(sums), "\n") {
379 parts := strings.Fields(line)
380 if len(parts) > 1 && parts[1] == name {
381 return parts[0]
382 }
383 }
384 return ""
385}
386
387// fetch the SHA256SUMS file provided, and verify its signature.
388func getPluginSHA256SUMs(sumsURL string) ([]byte, error) {
389 sigURL := sumsURL + ".sig"
390
391 sums, err := getFile(sumsURL)
392 if err != nil {
393 return nil, fmt.Errorf("error fetching checksums: %s", err)
394 }
395
396 sig, err := getFile(sigURL)
397 if err != nil {
398 return nil, fmt.Errorf("error fetching checksums signature: %s", err)
399 }
400
401 if err := verifySig(sums, sig); err != nil {
402 return nil, err
403 }
404
405 return sums, nil
406}
407
408func getFile(url string) ([]byte, error) {
409 resp, err := httpClient.Get(url)
410 if err != nil {
411 return nil, err
412 }
413 defer resp.Body.Close()
414
415 if resp.StatusCode != http.StatusOK {
416 return nil, fmt.Errorf("%s", resp.Status)
417 }
418
419 data, err := ioutil.ReadAll(resp.Body)
420 if err != nil {
421 return data, err
422 }
423 return data, nil
424}
diff --git a/vendor/github.com/hashicorp/terraform/plugin/discovery/meta.go b/vendor/github.com/hashicorp/terraform/plugin/discovery/meta.go
new file mode 100644
index 0000000..bdcebcb
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/plugin/discovery/meta.go
@@ -0,0 +1,41 @@
1package discovery
2
3import (
4 "crypto/sha256"
5 "io"
6 "os"
7)
8
9// PluginMeta is metadata about a plugin, useful for launching the plugin
10// and for understanding which plugins are available.
11type PluginMeta struct {
12 // Name is the name of the plugin, e.g. as inferred from the plugin
13 // binary's filename, or by explicit configuration.
14 Name string
15
16 // Version is the semver version of the plugin, expressed as a string
17 // that might not be semver-valid.
18 Version VersionStr
19
20 // Path is the absolute path of the executable that can be launched
21 // to provide the RPC server for this plugin.
22 Path string
23}
24
25// SHA256 returns a SHA256 hash of the content of the referenced executable
26// file, or an error if the file's contents cannot be read.
27func (m PluginMeta) SHA256() ([]byte, error) {
28 f, err := os.Open(m.Path)
29 if err != nil {
30 return nil, err
31 }
32 defer f.Close()
33
34 h := sha256.New()
35 _, err = io.Copy(h, f)
36 if err != nil {
37 return nil, err
38 }
39
40 return h.Sum(nil), nil
41}
diff --git a/vendor/github.com/hashicorp/terraform/plugin/discovery/meta_set.go b/vendor/github.com/hashicorp/terraform/plugin/discovery/meta_set.go
new file mode 100644
index 0000000..181ea1f
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/plugin/discovery/meta_set.go
@@ -0,0 +1,195 @@
1package discovery
2
3// A PluginMetaSet is a set of PluginMeta objects meeting a certain criteria.
4//
5// Methods on this type allow filtering of the set to produce subsets that
6// meet more restrictive criteria.
7type PluginMetaSet map[PluginMeta]struct{}
8
9// Add inserts the given PluginMeta into the receiving set. This is a no-op
10// if the given meta is already present.
11func (s PluginMetaSet) Add(p PluginMeta) {
12 s[p] = struct{}{}
13}
14
15// Remove removes the given PluginMeta from the receiving set. This is a no-op
16// if the given meta is not already present.
17func (s PluginMetaSet) Remove(p PluginMeta) {
18 delete(s, p)
19}
20
21// Has returns true if the given meta is in the receiving set, or false
22// otherwise.
23func (s PluginMetaSet) Has(p PluginMeta) bool {
24 _, ok := s[p]
25 return ok
26}
27
28// Count returns the number of metas in the set
29func (s PluginMetaSet) Count() int {
30 return len(s)
31}
32
33// ValidateVersions returns two new PluginMetaSets, separating those with
34// versions that have syntax-valid semver versions from those that don't.
35//
36// Eliminating invalid versions from consideration (and possibly warning about
37// them) is usually the first step of working with a meta set after discovery
38// has completed.
39func (s PluginMetaSet) ValidateVersions() (valid, invalid PluginMetaSet) {
40 valid = make(PluginMetaSet)
41 invalid = make(PluginMetaSet)
42 for p := range s {
43 if _, err := p.Version.Parse(); err == nil {
44 valid.Add(p)
45 } else {
46 invalid.Add(p)
47 }
48 }
49 return
50}
51
52// WithName returns the subset of metas that have the given name.
53func (s PluginMetaSet) WithName(name string) PluginMetaSet {
54 ns := make(PluginMetaSet)
55 for p := range s {
56 if p.Name == name {
57 ns.Add(p)
58 }
59 }
60 return ns
61}
62
63// WithVersion returns the subset of metas that have the given version.
64//
65// This should be used only with the "valid" result from ValidateVersions;
66// it will ignore any plugin metas that have a invalid version strings.
67func (s PluginMetaSet) WithVersion(version Version) PluginMetaSet {
68 ns := make(PluginMetaSet)
69 for p := range s {
70 gotVersion, err := p.Version.Parse()
71 if err != nil {
72 continue
73 }
74 if gotVersion.Equal(version) {
75 ns.Add(p)
76 }
77 }
78 return ns
79}
80
81// ByName groups the metas in the set by their Names, returning a map.
82func (s PluginMetaSet) ByName() map[string]PluginMetaSet {
83 ret := make(map[string]PluginMetaSet)
84 for p := range s {
85 if _, ok := ret[p.Name]; !ok {
86 ret[p.Name] = make(PluginMetaSet)
87 }
88 ret[p.Name].Add(p)
89 }
90 return ret
91}
92
93// Newest returns the one item from the set that has the newest Version value.
94//
95// The result is meaningful only if the set is already filtered such that
96// all of the metas have the same Name.
97//
98// If there isn't at least one meta in the set then this function will panic.
99// Use Count() to ensure that there is at least one value before calling.
100//
101// If any of the metas have invalid version strings then this function will
102// panic. Use ValidateVersions() first to filter out metas with invalid
103// versions.
104//
105// If two metas have the same Version then one is arbitrarily chosen. This
106// situation should be avoided by pre-filtering the set.
107func (s PluginMetaSet) Newest() PluginMeta {
108 if len(s) == 0 {
109 panic("can't call NewestStable on empty PluginMetaSet")
110 }
111
112 var first = true
113 var winner PluginMeta
114 var winnerVersion Version
115 for p := range s {
116 version, err := p.Version.Parse()
117 if err != nil {
118 panic(err)
119 }
120
121 if first == true || version.NewerThan(winnerVersion) {
122 winner = p
123 winnerVersion = version
124 first = false
125 }
126 }
127
128 return winner
129}
130
131// ConstrainVersions takes a set of requirements and attempts to
132// return a map from name to a set of metas that have the matching
133// name and an appropriate version.
134//
135// If any of the given requirements match *no* plugins then its PluginMetaSet
136// in the returned map will be empty.
137//
138// All viable metas are returned, so the caller can apply any desired filtering
139// to reduce down to a single option. For example, calling Newest() to obtain
140// the highest available version.
141//
142// If any of the metas in the set have invalid version strings then this
143// function will panic. Use ValidateVersions() first to filter out metas with
144// invalid versions.
145func (s PluginMetaSet) ConstrainVersions(reqd PluginRequirements) map[string]PluginMetaSet {
146 ret := make(map[string]PluginMetaSet)
147 for p := range s {
148 name := p.Name
149 allowedVersions, ok := reqd[name]
150 if !ok {
151 continue
152 }
153 if _, ok := ret[p.Name]; !ok {
154 ret[p.Name] = make(PluginMetaSet)
155 }
156 version, err := p.Version.Parse()
157 if err != nil {
158 panic(err)
159 }
160 if allowedVersions.Allows(version) {
161 ret[p.Name].Add(p)
162 }
163 }
164 return ret
165}
166
167// OverridePaths returns a new set where any existing plugins with the given
168// names are removed and replaced with the single path given in the map.
169//
170// This is here only to continue to support the legacy way of overriding
171// plugin binaries in the .terraformrc file. It treats all given plugins
172// as pre-versioning (version 0.0.0). This mechanism will eventually be
173// phased out, with vendor directories being the intended replacement.
174func (s PluginMetaSet) OverridePaths(paths map[string]string) PluginMetaSet {
175 ret := make(PluginMetaSet)
176 for p := range s {
177 if _, ok := paths[p.Name]; ok {
178 // Skip plugins that we're overridding
179 continue
180 }
181
182 ret.Add(p)
183 }
184
185 // Now add the metadata for overriding plugins
186 for name, path := range paths {
187 ret.Add(PluginMeta{
188 Name: name,
189 Version: VersionZero,
190 Path: path,
191 })
192 }
193
194 return ret
195}
diff --git a/vendor/github.com/hashicorp/terraform/plugin/discovery/requirements.go b/vendor/github.com/hashicorp/terraform/plugin/discovery/requirements.go
new file mode 100644
index 0000000..75430fd
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/plugin/discovery/requirements.go
@@ -0,0 +1,105 @@
1package discovery
2
3import (
4 "bytes"
5)
6
7// PluginRequirements describes a set of plugins (assumed to be of a consistent
8// kind) that are required to exist and have versions within the given
9// corresponding sets.
10type PluginRequirements map[string]*PluginConstraints
11
12// PluginConstraints represents an element of PluginRequirements describing
13// the constraints for a single plugin.
14type PluginConstraints struct {
15 // Specifies that the plugin's version must be within the given
16 // constraints.
17 Versions Constraints
18
19 // If non-nil, the hash of the on-disk plugin executable must exactly
20 // match the SHA256 hash given here.
21 SHA256 []byte
22}
23
24// Allows returns true if the given version is within the receiver's version
25// constraints.
26func (s *PluginConstraints) Allows(v Version) bool {
27 return s.Versions.Allows(v)
28}
29
30// AcceptsSHA256 returns true if the given executable SHA256 hash is acceptable,
31// either because it matches the constraint or because there is no such
32// constraint.
33func (s *PluginConstraints) AcceptsSHA256(digest []byte) bool {
34 if s.SHA256 == nil {
35 return true
36 }
37 return bytes.Equal(s.SHA256, digest)
38}
39
40// Merge takes the contents of the receiver and the other given requirements
41// object and merges them together into a single requirements structure
42// that satisfies both sets of requirements.
43//
44// Note that it doesn't make sense to merge two PluginRequirements with
45// differing required plugin SHA256 hashes, since the result will never
46// match any plugin.
47func (r PluginRequirements) Merge(other PluginRequirements) PluginRequirements {
48 ret := make(PluginRequirements)
49 for n, c := range r {
50 ret[n] = &PluginConstraints{
51 Versions: Constraints{}.Append(c.Versions),
52 SHA256: c.SHA256,
53 }
54 }
55 for n, c := range other {
56 if existing, exists := ret[n]; exists {
57 ret[n].Versions = ret[n].Versions.Append(c.Versions)
58
59 if existing.SHA256 != nil {
60 if c.SHA256 != nil && !bytes.Equal(c.SHA256, existing.SHA256) {
61 // If we've been asked to merge two constraints with
62 // different SHA256 hashes then we'll produce a dummy value
63 // that can never match anything. This is a silly edge case
64 // that no reasonable caller should hit.
65 ret[n].SHA256 = []byte(invalidProviderHash)
66 }
67 } else {
68 ret[n].SHA256 = c.SHA256 // might still be nil
69 }
70 } else {
71 ret[n] = &PluginConstraints{
72 Versions: Constraints{}.Append(c.Versions),
73 SHA256: c.SHA256,
74 }
75 }
76 }
77 return ret
78}
79
80// LockExecutables applies additional constraints to the receiver that
81// require plugin executables with specific SHA256 digests. This modifies
82// the receiver in-place, since it's intended to be applied after
83// version constraints have been resolved.
84//
85// The given map must include a key for every plugin that is already
86// required. If not, any missing keys will cause the corresponding plugin
87// to never match, though the direct caller doesn't necessarily need to
88// guarantee this as long as the downstream code _applying_ these constraints
89// is able to deal with the non-match in some way.
90func (r PluginRequirements) LockExecutables(sha256s map[string][]byte) {
91 for name, cons := range r {
92 digest := sha256s[name]
93
94 if digest == nil {
95 // Prevent any match, which will then presumably cause the
96 // downstream consumer of this requirements to report an error.
97 cons.SHA256 = []byte(invalidProviderHash)
98 continue
99 }
100
101 cons.SHA256 = digest
102 }
103}
104
105const invalidProviderHash = "<invalid>"
diff --git a/vendor/github.com/hashicorp/terraform/plugin/discovery/signature.go b/vendor/github.com/hashicorp/terraform/plugin/discovery/signature.go
new file mode 100644
index 0000000..b6686a5
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/plugin/discovery/signature.go
@@ -0,0 +1,53 @@
1package discovery
2
3import (
4 "bytes"
5 "log"
6 "strings"
7
8 "golang.org/x/crypto/openpgp"
9)
10
11// Verify the data using the provided openpgp detached signature and the
12// embedded hashicorp public key.
13func verifySig(data, sig []byte) error {
14 el, err := openpgp.ReadArmoredKeyRing(strings.NewReader(hashiPublicKey))
15 if err != nil {
16 log.Fatal(err)
17 }
18
19 _, err = openpgp.CheckDetachedSignature(el, bytes.NewReader(data), bytes.NewReader(sig))
20 return err
21}
22
23// this is the public key that signs the checksums file for releases.
24const hashiPublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
25Version: GnuPG v1
26
27mQENBFMORM0BCADBRyKO1MhCirazOSVwcfTr1xUxjPvfxD3hjUwHtjsOy/bT6p9f
28W2mRPfwnq2JB5As+paL3UGDsSRDnK9KAxQb0NNF4+eVhr/EJ18s3wwXXDMjpIifq
29fIm2WyH3G+aRLTLPIpscUNKDyxFOUbsmgXAmJ46Re1fn8uKxKRHbfa39aeuEYWFA
303drdL1WoUngvED7f+RnKBK2G6ZEpO+LDovQk19xGjiMTtPJrjMjZJ3QXqPvx5wca
31KSZLr4lMTuoTI/ZXyZy5bD4tShiZz6KcyX27cD70q2iRcEZ0poLKHyEIDAi3TM5k
32SwbbWBFd5RNPOR0qzrb/0p9ksKK48IIfH2FvABEBAAG0K0hhc2hpQ29ycCBTZWN1
33cml0eSA8c2VjdXJpdHlAaGFzaGljb3JwLmNvbT6JATgEEwECACIFAlMORM0CGwMG
34CwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEFGFLYc0j/xMyWIIAIPhcVqiQ59n
35Jc07gjUX0SWBJAxEG1lKxfzS4Xp+57h2xxTpdotGQ1fZwsihaIqow337YHQI3q0i
36SqV534Ms+j/tU7X8sq11xFJIeEVG8PASRCwmryUwghFKPlHETQ8jJ+Y8+1asRydi
37psP3B/5Mjhqv/uOK+Vy3zAyIpyDOMtIpOVfjSpCplVRdtSTFWBu9Em7j5I2HMn1w
38sJZnJgXKpybpibGiiTtmnFLOwibmprSu04rsnP4ncdC2XRD4wIjoyA+4PKgX3sCO
39klEzKryWYBmLkJOMDdo52LttP3279s7XrkLEE7ia0fXa2c12EQ0f0DQ1tGUvyVEW
40WmJVccm5bq25AQ0EUw5EzQEIANaPUY04/g7AmYkOMjaCZ6iTp9hB5Rsj/4ee/ln9
41wArzRO9+3eejLWh53FoN1rO+su7tiXJA5YAzVy6tuolrqjM8DBztPxdLBbEi4V+j
422tK0dATdBQBHEh3OJApO2UBtcjaZBT31zrG9K55D+CrcgIVEHAKY8Cb4kLBkb5wM
43skn+DrASKU0BNIV1qRsxfiUdQHZfSqtp004nrql1lbFMLFEuiY8FZrkkQ9qduixo
44mTT6f34/oiY+Jam3zCK7RDN/OjuWheIPGj/Qbx9JuNiwgX6yRj7OE1tjUx6d8g9y
450H1fmLJbb3WZZbuuGFnK6qrE3bGeY8+AWaJAZ37wpWh1p0cAEQEAAYkBHwQYAQIA
46CQUCUw5EzQIbDAAKCRBRhS2HNI/8TJntCAClU7TOO/X053eKF1jqNW4A1qpxctVc
47z8eTcY8Om5O4f6a/rfxfNFKn9Qyja/OG1xWNobETy7MiMXYjaa8uUx5iFy6kMVaP
480BXJ59NLZjMARGw6lVTYDTIvzqqqwLxgliSDfSnqUhubGwvykANPO+93BBx89MRG
49unNoYGXtPlhNFrAsB1VR8+EyKLv2HQtGCPSFBhrjuzH3gxGibNDDdFQLxxuJWepJ
50EK1UbTS4ms0NgZ2Uknqn1WRU1Ki7rE4sTy68iZtWpKQXZEJa0IGnuI2sSINGcXCJ
51oEIgXTMyCILo34Fa/C6VCm2WBgz9zZO8/rHIiQm1J5zqz0DrDwKBUM9C
52=LYpS
53-----END PGP PUBLIC KEY BLOCK-----`
diff --git a/vendor/github.com/hashicorp/terraform/plugin/discovery/version.go b/vendor/github.com/hashicorp/terraform/plugin/discovery/version.go
new file mode 100644
index 0000000..8fad58d
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/plugin/discovery/version.go
@@ -0,0 +1,72 @@
1package discovery
2
3import (
4 "fmt"
5 "sort"
6
7 version "github.com/hashicorp/go-version"
8)
9
10const VersionZero = "0.0.0"
11
12// A VersionStr is a string containing a possibly-invalid representation
13// of a semver version number. Call Parse on it to obtain a real Version
14// object, or discover that it is invalid.
15type VersionStr string
16
17// Parse transforms a VersionStr into a Version if it is
18// syntactically valid. If it isn't then an error is returned instead.
19func (s VersionStr) Parse() (Version, error) {
20 raw, err := version.NewVersion(string(s))
21 if err != nil {
22 return Version{}, err
23 }
24 return Version{raw}, nil
25}
26
27// MustParse transforms a VersionStr into a Version if it is
28// syntactically valid. If it isn't then it panics.
29func (s VersionStr) MustParse() Version {
30 ret, err := s.Parse()
31 if err != nil {
32 panic(err)
33 }
34 return ret
35}
36
37// Version represents a version number that has been parsed from
38// a semver string and known to be valid.
39type Version struct {
40 // We wrap this here just because it avoids a proliferation of
41 // direct go-version imports all over the place, and keeps the
42 // version-processing details within this package.
43 raw *version.Version
44}
45
46func (v Version) String() string {
47 return v.raw.String()
48}
49
50func (v Version) NewerThan(other Version) bool {
51 return v.raw.GreaterThan(other.raw)
52}
53
54func (v Version) Equal(other Version) bool {
55 return v.raw.Equal(other.raw)
56}
57
58// MinorUpgradeConstraintStr returns a ConstraintStr that would permit
59// minor upgrades relative to the receiving version.
60func (v Version) MinorUpgradeConstraintStr() ConstraintStr {
61 segments := v.raw.Segments()
62 return ConstraintStr(fmt.Sprintf("~> %d.%d", segments[0], segments[1]))
63}
64
65type Versions []Version
66
67// Sort sorts version from newest to oldest.
68func (v Versions) Sort() {
69 sort.Slice(v, func(i, j int) bool {
70 return v[i].NewerThan(v[j])
71 })
72}
diff --git a/vendor/github.com/hashicorp/terraform/plugin/discovery/version_set.go b/vendor/github.com/hashicorp/terraform/plugin/discovery/version_set.go
new file mode 100644
index 0000000..0aefd75
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/plugin/discovery/version_set.go
@@ -0,0 +1,84 @@
1package discovery
2
3import (
4 "sort"
5
6 version "github.com/hashicorp/go-version"
7)
8
9// A ConstraintStr is a string containing a possibly-invalid representation
10// of a version constraint provided in configuration. Call Parse on it to
11// obtain a real Constraint object, or discover that it is invalid.
12type ConstraintStr string
13
14// Parse transforms a ConstraintStr into a Constraints if it is
15// syntactically valid. If it isn't then an error is returned instead.
16func (s ConstraintStr) Parse() (Constraints, error) {
17 raw, err := version.NewConstraint(string(s))
18 if err != nil {
19 return Constraints{}, err
20 }
21 return Constraints{raw}, nil
22}
23
24// MustParse is like Parse but it panics if the constraint string is invalid.
25func (s ConstraintStr) MustParse() Constraints {
26 ret, err := s.Parse()
27 if err != nil {
28 panic(err)
29 }
30 return ret
31}
32
33// Constraints represents a set of versions which any given Version is either
34// a member of or not.
35type Constraints struct {
36 raw version.Constraints
37}
38
39// AllVersions is a Constraints containing all versions
40var AllVersions Constraints
41
42func init() {
43 AllVersions = Constraints{
44 raw: make(version.Constraints, 0),
45 }
46}
47
48// Allows returns true if the given version permitted by the receiving
49// constraints set.
50func (s Constraints) Allows(v Version) bool {
51 return s.raw.Check(v.raw)
52}
53
54// Append combines the receiving set with the given other set to produce
55// a set that is the intersection of both sets, which is to say that resulting
56// constraints contain only the versions that are members of both.
57func (s Constraints) Append(other Constraints) Constraints {
58 raw := make(version.Constraints, 0, len(s.raw)+len(other.raw))
59
60 // Since "raw" is a list of constraints that remove versions from the set,
61 // "Intersection" is implemented by concatenating together those lists,
62 // thus leaving behind only the versions not removed by either list.
63 raw = append(raw, s.raw...)
64 raw = append(raw, other.raw...)
65
66 // while the set is unordered, we sort these lexically for consistent output
67 sort.Slice(raw, func(i, j int) bool {
68 return raw[i].String() < raw[j].String()
69 })
70
71 return Constraints{raw}
72}
73
74// String returns a string representation of the set members as a set
75// of range constraints.
76func (s Constraints) String() string {
77 return s.raw.String()
78}
79
80// Unconstrained returns true if and only if the receiver is an empty
81// constraint set.
82func (s Constraints) Unconstrained() bool {
83 return len(s.raw) == 0
84}
diff --git a/vendor/github.com/hashicorp/terraform/terraform/context.go b/vendor/github.com/hashicorp/terraform/terraform/context.go
index 306128e..a814a85 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/context.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/context.go
@@ -57,12 +57,17 @@ type ContextOpts struct {
57 Parallelism int 57 Parallelism int
58 State *State 58 State *State
59 StateFutureAllowed bool 59 StateFutureAllowed bool
60 Providers map[string]ResourceProviderFactory 60 ProviderResolver ResourceProviderResolver
61 Provisioners map[string]ResourceProvisionerFactory 61 Provisioners map[string]ResourceProvisionerFactory
62 Shadow bool 62 Shadow bool
63 Targets []string 63 Targets []string
64 Variables map[string]interface{} 64 Variables map[string]interface{}
65 65
66 // If non-nil, will apply as additional constraints on the provider
67 // plugins that will be requested from the provider resolver.
68 ProviderSHA256s map[string][]byte
69 SkipProviderVerify bool
70
66 UIInput UIInput 71 UIInput UIInput
67} 72}
68 73
@@ -102,6 +107,7 @@ type Context struct {
102 l sync.Mutex // Lock acquired during any task 107 l sync.Mutex // Lock acquired during any task
103 parallelSem Semaphore 108 parallelSem Semaphore
104 providerInputConfig map[string]map[string]interface{} 109 providerInputConfig map[string]map[string]interface{}
110 providerSHA256s map[string][]byte
105 runLock sync.Mutex 111 runLock sync.Mutex
106 runCond *sync.Cond 112 runCond *sync.Cond
107 runContext context.Context 113 runContext context.Context
@@ -166,7 +172,6 @@ func NewContext(opts *ContextOpts) (*Context, error) {
166 // set by environment variables if necessary. This includes 172 // set by environment variables if necessary. This includes
167 // values taken from -var-file in addition. 173 // values taken from -var-file in addition.
168 variables := make(map[string]interface{}) 174 variables := make(map[string]interface{})
169
170 if opts.Module != nil { 175 if opts.Module != nil {
171 var err error 176 var err error
172 variables, err = Variables(opts.Module, opts.Variables) 177 variables, err = Variables(opts.Module, opts.Variables)
@@ -175,6 +180,23 @@ func NewContext(opts *ContextOpts) (*Context, error) {
175 } 180 }
176 } 181 }
177 182
183 // Bind available provider plugins to the constraints in config
184 var providers map[string]ResourceProviderFactory
185 if opts.ProviderResolver != nil {
186 var err error
187 deps := ModuleTreeDependencies(opts.Module, state)
188 reqd := deps.AllPluginRequirements()
189 if opts.ProviderSHA256s != nil && !opts.SkipProviderVerify {
190 reqd.LockExecutables(opts.ProviderSHA256s)
191 }
192 providers, err = resourceProviderFactories(opts.ProviderResolver, reqd)
193 if err != nil {
194 return nil, err
195 }
196 } else {
197 providers = make(map[string]ResourceProviderFactory)
198 }
199
178 diff := opts.Diff 200 diff := opts.Diff
179 if diff == nil { 201 if diff == nil {
180 diff = &Diff{} 202 diff = &Diff{}
@@ -182,7 +204,7 @@ func NewContext(opts *ContextOpts) (*Context, error) {
182 204
183 return &Context{ 205 return &Context{
184 components: &basicComponentFactory{ 206 components: &basicComponentFactory{
185 providers: opts.Providers, 207 providers: providers,
186 provisioners: opts.Provisioners, 208 provisioners: opts.Provisioners,
187 }, 209 },
188 destroy: opts.Destroy, 210 destroy: opts.Destroy,
@@ -198,6 +220,7 @@ func NewContext(opts *ContextOpts) (*Context, error) {
198 220
199 parallelSem: NewSemaphore(par), 221 parallelSem: NewSemaphore(par),
200 providerInputConfig: make(map[string]map[string]interface{}), 222 providerInputConfig: make(map[string]map[string]interface{}),
223 providerSHA256s: opts.ProviderSHA256s,
201 sh: sh, 224 sh: sh,
202 }, nil 225 }, nil
203} 226}
@@ -509,6 +532,9 @@ func (c *Context) Plan() (*Plan, error) {
509 Vars: c.variables, 532 Vars: c.variables,
510 State: c.state, 533 State: c.state,
511 Targets: c.targets, 534 Targets: c.targets,
535
536 TerraformVersion: VersionString(),
537 ProviderSHA256s: c.providerSHA256s,
512 } 538 }
513 539
514 var operation walkOperation 540 var operation walkOperation
diff --git a/vendor/github.com/hashicorp/terraform/terraform/diff.go b/vendor/github.com/hashicorp/terraform/terraform/diff.go
index a9fae6c..fd1687e 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/diff.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/diff.go
@@ -28,7 +28,7 @@ const (
28// multiVal matches the index key to a flatmapped set, list or map 28// multiVal matches the index key to a flatmapped set, list or map
29var multiVal = regexp.MustCompile(`\.(#|%)$`) 29var multiVal = regexp.MustCompile(`\.(#|%)$`)
30 30
31// Diff trackes the changes that are necessary to apply a configuration 31// Diff tracks the changes that are necessary to apply a configuration
32// to an existing infrastructure. 32// to an existing infrastructure.
33type Diff struct { 33type Diff struct {
34 // Modules contains all the modules that have a diff 34 // Modules contains all the modules that have a diff
@@ -370,7 +370,7 @@ type InstanceDiff struct {
370 370
371 // Meta is a simple K/V map that is stored in a diff and persisted to 371 // Meta is a simple K/V map that is stored in a diff and persisted to
372 // plans but otherwise is completely ignored by Terraform core. It is 372 // plans but otherwise is completely ignored by Terraform core. It is
373 // mean to be used for additional data a resource may want to pass through. 373 // meant to be used for additional data a resource may want to pass through.
374 // The value here must only contain Go primitives and collections. 374 // The value here must only contain Go primitives and collections.
375 Meta map[string]interface{} 375 Meta map[string]interface{}
376} 376}
@@ -551,7 +551,7 @@ func (d *InstanceDiff) SetDestroyDeposed(b bool) {
551} 551}
552 552
553// These methods are properly locked, for use outside other InstanceDiff 553// These methods are properly locked, for use outside other InstanceDiff
554// methods but everywhere else within in the terraform package. 554// methods but everywhere else within the terraform package.
555// TODO refactor the locking scheme 555// TODO refactor the locking scheme
556func (d *InstanceDiff) SetTainted(b bool) { 556func (d *InstanceDiff) SetTainted(b bool) {
557 d.mu.Lock() 557 d.mu.Lock()
diff --git a/vendor/github.com/hashicorp/terraform/terraform/eval_diff.go b/vendor/github.com/hashicorp/terraform/terraform/eval_diff.go
index 6f09526..c35f908 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/eval_diff.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/eval_diff.go
@@ -81,6 +81,12 @@ type EvalDiff struct {
81 // Resource is needed to fetch the ignore_changes list so we can 81 // Resource is needed to fetch the ignore_changes list so we can
82 // filter user-requested ignored attributes from the diff. 82 // filter user-requested ignored attributes from the diff.
83 Resource *config.Resource 83 Resource *config.Resource
84
85 // Stub is used to flag the generated InstanceDiff as a stub. This is used to
86 // ensure that the node exists to perform interpolations and generate
87 // computed paths off of, but not as an actual diff where resouces should be
88 // counted, and not as a diff that should be acted on.
89 Stub bool
84} 90}
85 91
86// TODO: test 92// TODO: test
@@ -90,11 +96,13 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
90 provider := *n.Provider 96 provider := *n.Provider
91 97
92 // Call pre-diff hook 98 // Call pre-diff hook
93 err := ctx.Hook(func(h Hook) (HookAction, error) { 99 if !n.Stub {
94 return h.PreDiff(n.Info, state) 100 err := ctx.Hook(func(h Hook) (HookAction, error) {
95 }) 101 return h.PreDiff(n.Info, state)
96 if err != nil { 102 })
97 return nil, err 103 if err != nil {
104 return nil, err
105 }
98 } 106 }
99 107
100 // The state for the diff must never be nil 108 // The state for the diff must never be nil
@@ -158,15 +166,19 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
158 } 166 }
159 167
160 // Call post-refresh hook 168 // Call post-refresh hook
161 err = ctx.Hook(func(h Hook) (HookAction, error) { 169 if !n.Stub {
162 return h.PostDiff(n.Info, diff) 170 err = ctx.Hook(func(h Hook) (HookAction, error) {
163 }) 171 return h.PostDiff(n.Info, diff)
164 if err != nil { 172 })
165 return nil, err 173 if err != nil {
174 return nil, err
175 }
166 } 176 }
167 177
168 // Update our output 178 // Update our output if we care
169 *n.OutputDiff = diff 179 if n.OutputDiff != nil {
180 *n.OutputDiff = diff
181 }
170 182
171 // Update the state if we care 183 // Update the state if we care
172 if n.OutputState != nil { 184 if n.OutputState != nil {
diff --git a/vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go b/vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go
index a6a3a90..4b29bbb 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/graph_builder_plan.go
@@ -117,7 +117,15 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
117 &CountBoundaryTransformer{}, 117 &CountBoundaryTransformer{},
118 118
119 // Target 119 // Target
120 &TargetsTransformer{Targets: b.Targets}, 120 &TargetsTransformer{
121 Targets: b.Targets,
122
123 // Resource nodes from config have not yet been expanded for
124 // "count", so we must apply targeting without indices. Exact
125 // targeting will be dealt with later when these resources
126 // DynamicExpand.
127 IgnoreIndices: true,
128 },
121 129
122 // Close opened plugin connections 130 // Close opened plugin connections
123 &CloseProviderTransformer{}, 131 &CloseProviderTransformer{},
diff --git a/vendor/github.com/hashicorp/terraform/terraform/graph_builder_refresh.go b/vendor/github.com/hashicorp/terraform/terraform/graph_builder_refresh.go
index 0634f96..3d3e968 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/graph_builder_refresh.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/graph_builder_refresh.go
@@ -144,7 +144,15 @@ func (b *RefreshGraphBuilder) Steps() []GraphTransformer {
144 &ReferenceTransformer{}, 144 &ReferenceTransformer{},
145 145
146 // Target 146 // Target
147 &TargetsTransformer{Targets: b.Targets}, 147 &TargetsTransformer{
148 Targets: b.Targets,
149
150 // Resource nodes from config have not yet been expanded for
151 // "count", so we must apply targeting without indices. Exact
152 // targeting will be dealt with later when these resources
153 // DynamicExpand.
154 IgnoreIndices: true,
155 },
148 156
149 // Close opened plugin connections 157 // Close opened plugin connections
150 &CloseProviderTransformer{}, 158 &CloseProviderTransformer{},
diff --git a/vendor/github.com/hashicorp/terraform/terraform/interpolate.go b/vendor/github.com/hashicorp/terraform/terraform/interpolate.go
index 0def295..22ddce6 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/interpolate.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/interpolate.go
@@ -317,9 +317,13 @@ func (i *Interpolater) valueTerraformVar(
317 n string, 317 n string,
318 v *config.TerraformVariable, 318 v *config.TerraformVariable,
319 result map[string]ast.Variable) error { 319 result map[string]ast.Variable) error {
320 if v.Field != "env" { 320
321 // "env" is supported for backward compatibility, but it's deprecated and
322 // so we won't advertise it as being allowed in the error message. It will
323 // be removed in a future version of Terraform.
324 if v.Field != "workspace" && v.Field != "env" {
321 return fmt.Errorf( 325 return fmt.Errorf(
322 "%s: only supported key for 'terraform.X' interpolations is 'env'", n) 326 "%s: only supported key for 'terraform.X' interpolations is 'workspace'", n)
323 } 327 }
324 328
325 if i.Meta == nil { 329 if i.Meta == nil {
diff --git a/vendor/github.com/hashicorp/terraform/terraform/module_dependencies.go b/vendor/github.com/hashicorp/terraform/terraform/module_dependencies.go
new file mode 100644
index 0000000..b9f44a0
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/terraform/module_dependencies.go
@@ -0,0 +1,156 @@
1package terraform
2
3import (
4 "github.com/hashicorp/terraform/config"
5 "github.com/hashicorp/terraform/config/module"
6 "github.com/hashicorp/terraform/moduledeps"
7 "github.com/hashicorp/terraform/plugin/discovery"
8)
9
10// ModuleTreeDependencies returns the dependencies of the tree of modules
11// described by the given configuration tree and state.
12//
13// Both configuration and state are required because there can be resources
14// implied by instances in the state that no longer exist in config.
15//
16// This function will panic if any invalid version constraint strings are
17// present in the configuration. This is guaranteed not to happen for any
18// configuration that has passed a call to Config.Validate().
19func ModuleTreeDependencies(root *module.Tree, state *State) *moduledeps.Module {
20
21 // First we walk the configuration tree to build the overall structure
22 // and capture the explicit/implicit/inherited provider dependencies.
23 deps := moduleTreeConfigDependencies(root, nil)
24
25 // Next we walk over the resources in the state to catch any additional
26 // dependencies created by existing resources that are no longer in config.
27 // Most things we find in state will already be present in 'deps', but
28 // we're interested in the rare thing that isn't.
29 moduleTreeMergeStateDependencies(deps, state)
30
31 return deps
32}
33
34func moduleTreeConfigDependencies(root *module.Tree, inheritProviders map[string]*config.ProviderConfig) *moduledeps.Module {
35 if root == nil {
36 // If no config is provided, we'll make a synthetic root.
37 // This isn't necessarily correct if we're called with a nil that
38 // *isn't* at the root, but in practice that can never happen.
39 return &moduledeps.Module{
40 Name: "root",
41 }
42 }
43
44 ret := &moduledeps.Module{
45 Name: root.Name(),
46 }
47
48 cfg := root.Config()
49 providerConfigs := cfg.ProviderConfigsByFullName()
50
51 // Provider dependencies
52 {
53 providers := make(moduledeps.Providers, len(providerConfigs))
54
55 // Any providerConfigs elements are *explicit* provider dependencies,
56 // which is the only situation where the user might provide an actual
57 // version constraint. We'll take care of these first.
58 for fullName, pCfg := range providerConfigs {
59 inst := moduledeps.ProviderInstance(fullName)
60 versionSet := discovery.AllVersions
61 if pCfg.Version != "" {
62 versionSet = discovery.ConstraintStr(pCfg.Version).MustParse()
63 }
64 providers[inst] = moduledeps.ProviderDependency{
65 Constraints: versionSet,
66 Reason: moduledeps.ProviderDependencyExplicit,
67 }
68 }
69
70 // Each resource in the configuration creates an *implicit* provider
71 // dependency, though we'll only record it if there isn't already
72 // an explicit dependency on the same provider.
73 for _, rc := range cfg.Resources {
74 fullName := rc.ProviderFullName()
75 inst := moduledeps.ProviderInstance(fullName)
76 if _, exists := providers[inst]; exists {
77 // Explicit dependency already present
78 continue
79 }
80
81 reason := moduledeps.ProviderDependencyImplicit
82 if _, inherited := inheritProviders[fullName]; inherited {
83 reason = moduledeps.ProviderDependencyInherited
84 }
85
86 providers[inst] = moduledeps.ProviderDependency{
87 Constraints: discovery.AllVersions,
88 Reason: reason,
89 }
90 }
91
92 ret.Providers = providers
93 }
94
95 childInherit := make(map[string]*config.ProviderConfig)
96 for k, v := range inheritProviders {
97 childInherit[k] = v
98 }
99 for k, v := range providerConfigs {
100 childInherit[k] = v
101 }
102 for _, c := range root.Children() {
103 ret.Children = append(ret.Children, moduleTreeConfigDependencies(c, childInherit))
104 }
105
106 return ret
107}
108
109func moduleTreeMergeStateDependencies(root *moduledeps.Module, state *State) {
110 if state == nil {
111 return
112 }
113
114 findModule := func(path []string) *moduledeps.Module {
115 module := root
116 for _, name := range path[1:] { // skip initial "root"
117 var next *moduledeps.Module
118 for _, cm := range module.Children {
119 if cm.Name == name {
120 next = cm
121 break
122 }
123 }
124
125 if next == nil {
126 // If we didn't find a next node, we'll need to make one
127 next = &moduledeps.Module{
128 Name: name,
129 }
130 module.Children = append(module.Children, next)
131 }
132
133 module = next
134 }
135 return module
136 }
137
138 for _, ms := range state.Modules {
139 module := findModule(ms.Path)
140
141 for _, is := range ms.Resources {
142 fullName := config.ResourceProviderFullName(is.Type, is.Provider)
143 inst := moduledeps.ProviderInstance(fullName)
144 if _, exists := module.Providers[inst]; !exists {
145 if module.Providers == nil {
146 module.Providers = make(moduledeps.Providers)
147 }
148 module.Providers[inst] = moduledeps.ProviderDependency{
149 Constraints: discovery.AllVersions,
150 Reason: moduledeps.ProviderDependencyFromState,
151 }
152 }
153 }
154 }
155
156}
diff --git a/vendor/github.com/hashicorp/terraform/terraform/node_resource_refresh.go b/vendor/github.com/hashicorp/terraform/terraform/node_resource_refresh.go
index 6ab9df7..cd4fe92 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/node_resource_refresh.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/node_resource_refresh.go
@@ -45,13 +45,6 @@ func (n *NodeRefreshableManagedResource) DynamicExpand(ctx EvalContext) (*Graph,
45 Addr: n.ResourceAddr(), 45 Addr: n.ResourceAddr(),
46 }, 46 },
47 47
48 // Switch up any node missing state to a plannable resource. This helps
49 // catch cases where data sources depend on the counts from this resource
50 // during a scale out.
51 &ResourceRefreshPlannableTransformer{
52 State: state,
53 },
54
55 // Add the count orphans to make sure these resources are accounted for 48 // Add the count orphans to make sure these resources are accounted for
56 // during a scale in. 49 // during a scale in.
57 &OrphanResourceCountTransformer{ 50 &OrphanResourceCountTransformer{
@@ -100,6 +93,9 @@ func (n *NodeRefreshableManagedResourceInstance) EvalTree() EvalNode {
100 // Eval info is different depending on what kind of resource this is 93 // Eval info is different depending on what kind of resource this is
101 switch mode := n.Addr.Mode; mode { 94 switch mode := n.Addr.Mode; mode {
102 case config.ManagedResourceMode: 95 case config.ManagedResourceMode:
96 if n.ResourceState == nil {
97 return n.evalTreeManagedResourceNoState()
98 }
103 return n.evalTreeManagedResource() 99 return n.evalTreeManagedResource()
104 100
105 case config.DataResourceMode: 101 case config.DataResourceMode:
@@ -176,3 +172,88 @@ func (n *NodeRefreshableManagedResourceInstance) evalTreeManagedResource() EvalN
176 }, 172 },
177 } 173 }
178} 174}
175
176// evalTreeManagedResourceNoState produces an EvalSequence for refresh resource
177// nodes that don't have state attached. An example of where this functionality
178// is useful is when a resource that already exists in state is being scaled
179// out, ie: has its resource count increased. In this case, the scaled out node
180// needs to be available to other nodes (namely data sources) that may depend
181// on it for proper interpolation, or confusing "index out of range" errors can
182// occur.
183//
184// The steps in this sequence are very similar to the steps carried out in
185// plan, but nothing is done with the diff after it is created - it is dropped,
186// and its changes are not counted in the UI.
187func (n *NodeRefreshableManagedResourceInstance) evalTreeManagedResourceNoState() EvalNode {
188 // Declare a bunch of variables that are used for state during
189 // evaluation. Most of this are written to by-address below.
190 var provider ResourceProvider
191 var state *InstanceState
192 var resourceConfig *ResourceConfig
193
194 addr := n.NodeAbstractResource.Addr
195 stateID := addr.stateId()
196 info := &InstanceInfo{
197 Id: stateID,
198 Type: addr.Type,
199 ModulePath: normalizeModulePath(addr.Path),
200 }
201
202 // Build the resource for eval
203 resource := &Resource{
204 Name: addr.Name,
205 Type: addr.Type,
206 CountIndex: addr.Index,
207 }
208 if resource.CountIndex < 0 {
209 resource.CountIndex = 0
210 }
211
212 // Determine the dependencies for the state.
213 stateDeps := n.StateReferences()
214
215 return &EvalSequence{
216 Nodes: []EvalNode{
217 &EvalInterpolate{
218 Config: n.Config.RawConfig.Copy(),
219 Resource: resource,
220 Output: &resourceConfig,
221 },
222 &EvalGetProvider{
223 Name: n.ProvidedBy()[0],
224 Output: &provider,
225 },
226 // Re-run validation to catch any errors we missed, e.g. type
227 // mismatches on computed values.
228 &EvalValidateResource{
229 Provider: &provider,
230 Config: &resourceConfig,
231 ResourceName: n.Config.Name,
232 ResourceType: n.Config.Type,
233 ResourceMode: n.Config.Mode,
234 IgnoreWarnings: true,
235 },
236 &EvalReadState{
237 Name: stateID,
238 Output: &state,
239 },
240 &EvalDiff{
241 Name: stateID,
242 Info: info,
243 Config: &resourceConfig,
244 Resource: n.Config,
245 Provider: &provider,
246 State: &state,
247 OutputState: &state,
248 Stub: true,
249 },
250 &EvalWriteState{
251 Name: stateID,
252 ResourceType: n.Config.Type,
253 Provider: n.Config.Provider,
254 Dependencies: stateDeps,
255 State: &state,
256 },
257 },
258 }
259}
diff --git a/vendor/github.com/hashicorp/terraform/terraform/plan.go b/vendor/github.com/hashicorp/terraform/terraform/plan.go
index ea08845..51d6652 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/plan.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/plan.go
@@ -6,6 +6,7 @@ import (
6 "errors" 6 "errors"
7 "fmt" 7 "fmt"
8 "io" 8 "io"
9 "log"
9 "sync" 10 "sync"
10 11
11 "github.com/hashicorp/terraform/config/module" 12 "github.com/hashicorp/terraform/config/module"
@@ -31,6 +32,9 @@ type Plan struct {
31 Vars map[string]interface{} 32 Vars map[string]interface{}
32 Targets []string 33 Targets []string
33 34
35 TerraformVersion string
36 ProviderSHA256s map[string][]byte
37
34 // Backend is the backend that this plan should use and store data with. 38 // Backend is the backend that this plan should use and store data with.
35 Backend *BackendState 39 Backend *BackendState
36 40
@@ -40,19 +44,58 @@ type Plan struct {
40// Context returns a Context with the data encapsulated in this plan. 44// Context returns a Context with the data encapsulated in this plan.
41// 45//
42// The following fields in opts are overridden by the plan: Config, 46// The following fields in opts are overridden by the plan: Config,
43// Diff, State, Variables. 47// Diff, Variables.
48//
49// If State is not provided, it is set from the plan. If it _is_ provided,
50// it must be Equal to the state stored in plan, but may have a newer
51// serial.
44func (p *Plan) Context(opts *ContextOpts) (*Context, error) { 52func (p *Plan) Context(opts *ContextOpts) (*Context, error) {
53 var err error
54 opts, err = p.contextOpts(opts)
55 if err != nil {
56 return nil, err
57 }
58 return NewContext(opts)
59}
60
61// contextOpts mutates the given base ContextOpts in place to use input
62// objects obtained from the receiving plan.
63func (p *Plan) contextOpts(base *ContextOpts) (*ContextOpts, error) {
64 opts := base
65
45 opts.Diff = p.Diff 66 opts.Diff = p.Diff
46 opts.Module = p.Module 67 opts.Module = p.Module
47 opts.State = p.State
48 opts.Targets = p.Targets 68 opts.Targets = p.Targets
69 opts.ProviderSHA256s = p.ProviderSHA256s
70
71 if opts.State == nil {
72 opts.State = p.State
73 } else if !opts.State.Equal(p.State) {
74 // Even if we're overriding the state, it should be logically equal
75 // to what's in plan. The only valid change to have made by the time
76 // we get here is to have incremented the serial.
77 //
78 // Due to the fact that serialization may change the representation of
79 // the state, there is little chance that these aren't actually equal.
80 // Log the error condition for reference, but continue with the state
81 // we have.
82 log.Println("[WARNING] Plan state and ContextOpts state are not equal")
83 }
84
85 thisVersion := VersionString()
86 if p.TerraformVersion != "" && p.TerraformVersion != thisVersion {
87 return nil, fmt.Errorf(
88 "plan was created with a different version of Terraform (created with %s, but running %s)",
89 p.TerraformVersion, thisVersion,
90 )
91 }
49 92
50 opts.Variables = make(map[string]interface{}) 93 opts.Variables = make(map[string]interface{})
51 for k, v := range p.Vars { 94 for k, v := range p.Vars {
52 opts.Variables[k] = v 95 opts.Variables[k] = v
53 } 96 }
54 97
55 return NewContext(opts) 98 return opts, nil
56} 99}
57 100
58func (p *Plan) String() string { 101func (p *Plan) String() string {
@@ -86,7 +129,7 @@ func (p *Plan) init() {
86// the ability in the future to change the file format if we want for any 129// the ability in the future to change the file format if we want for any
87// reason. 130// reason.
88const planFormatMagic = "tfplan" 131const planFormatMagic = "tfplan"
89const planFormatVersion byte = 1 132const planFormatVersion byte = 2
90 133
91// ReadPlan reads a plan structure out of a reader in the format that 134// ReadPlan reads a plan structure out of a reader in the format that
92// was written by WritePlan. 135// was written by WritePlan.
diff --git a/vendor/github.com/hashicorp/terraform/terraform/resource_address.go b/vendor/github.com/hashicorp/terraform/terraform/resource_address.go
index a8a0c95..8badca8 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/resource_address.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/resource_address.go
@@ -8,6 +8,7 @@ import (
8 "strings" 8 "strings"
9 9
10 "github.com/hashicorp/terraform/config" 10 "github.com/hashicorp/terraform/config"
11 "github.com/hashicorp/terraform/config/module"
11) 12)
12 13
13// ResourceAddress is a way of identifying an individual resource (or, 14// ResourceAddress is a way of identifying an individual resource (or,
@@ -89,6 +90,51 @@ func (r *ResourceAddress) String() string {
89 return strings.Join(result, ".") 90 return strings.Join(result, ".")
90} 91}
91 92
93// HasResourceSpec returns true if the address has a resource spec, as
94// defined in the documentation:
95// https://www.terraform.io/docs/internals/resource-addressing.html
96// In particular, this returns false if the address contains only
97// a module path, thus addressing the entire module.
98func (r *ResourceAddress) HasResourceSpec() bool {
99 return r.Type != "" && r.Name != ""
100}
101
102// WholeModuleAddress returns the resource address that refers to all
103// resources in the same module as the receiver address.
104func (r *ResourceAddress) WholeModuleAddress() *ResourceAddress {
105 return &ResourceAddress{
106 Path: r.Path,
107 Index: -1,
108 InstanceTypeSet: false,
109 }
110}
111
112// MatchesConfig returns true if the receiver matches the given
113// configuration resource within the given configuration module.
114//
115// Since resource configuration blocks represent all of the instances of
116// a multi-instance resource, the index of the address (if any) is not
117// considered.
118func (r *ResourceAddress) MatchesConfig(mod *module.Tree, rc *config.Resource) bool {
119 if r.HasResourceSpec() {
120 if r.Mode != rc.Mode || r.Type != rc.Type || r.Name != rc.Name {
121 return false
122 }
123 }
124
125 addrPath := r.Path
126 cfgPath := mod.Path()
127
128 // normalize
129 if len(addrPath) == 0 {
130 addrPath = nil
131 }
132 if len(cfgPath) == 0 {
133 cfgPath = nil
134 }
135 return reflect.DeepEqual(addrPath, cfgPath)
136}
137
92// stateId returns the ID that this resource should be entered with 138// stateId returns the ID that this resource should be entered with
93// in the state. This is also used for diffs. In the future, we'd like to 139// in the state. This is also used for diffs. In the future, we'd like to
94// move away from this string field so I don't export this. 140// move away from this string field so I don't export this.
@@ -185,7 +231,10 @@ func ParseResourceAddress(s string) (*ResourceAddress, error) {
185 231
186 // not allowed to say "data." without a type following 232 // not allowed to say "data." without a type following
187 if mode == config.DataResourceMode && matches["type"] == "" { 233 if mode == config.DataResourceMode && matches["type"] == "" {
188 return nil, fmt.Errorf("must target specific data instance") 234 return nil, fmt.Errorf(
235 "invalid resource address %q: must target specific data instance",
236 s,
237 )
189 } 238 }
190 239
191 return &ResourceAddress{ 240 return &ResourceAddress{
@@ -199,6 +248,75 @@ func ParseResourceAddress(s string) (*ResourceAddress, error) {
199 }, nil 248 }, nil
200} 249}
201 250
251// ParseResourceAddressForInstanceDiff creates a ResourceAddress for a
252// resource name as described in a module diff.
253//
254// For historical reasons a different addressing format is used in this
255// context. The internal format should not be shown in the UI and instead
256// this function should be used to translate to a ResourceAddress and
257// then, where appropriate, use the String method to produce a canonical
258// resource address string for display in the UI.
259//
260// The given path slice must be empty (or nil) for the root module, and
261// otherwise consist of a sequence of module names traversing down into
262// the module tree. If a non-nil path is provided, the caller must not
263// modify its underlying array after passing it to this function.
264func ParseResourceAddressForInstanceDiff(path []string, key string) (*ResourceAddress, error) {
265 addr, err := parseResourceAddressInternal(key)
266 if err != nil {
267 return nil, err
268 }
269 addr.Path = path
270 return addr, nil
271}
272
273// Contains returns true if and only if the given node is contained within
274// the receiver.
275//
276// Containment is defined in terms of the module and resource heirarchy:
277// a resource is contained within its module and any ancestor modules,
278// an indexed resource instance is contained with the unindexed resource, etc.
279func (addr *ResourceAddress) Contains(other *ResourceAddress) bool {
280 ourPath := addr.Path
281 givenPath := other.Path
282 if len(givenPath) < len(ourPath) {
283 return false
284 }
285 for i := range ourPath {
286 if ourPath[i] != givenPath[i] {
287 return false
288 }
289 }
290
291 // If the receiver is a whole-module address then the path prefix
292 // matching is all we need.
293 if !addr.HasResourceSpec() {
294 return true
295 }
296
297 if addr.Type != other.Type || addr.Name != other.Name || addr.Mode != other.Mode {
298 return false
299 }
300
301 if addr.Index != -1 && addr.Index != other.Index {
302 return false
303 }
304
305 if addr.InstanceTypeSet && (addr.InstanceTypeSet != other.InstanceTypeSet || addr.InstanceType != other.InstanceType) {
306 return false
307 }
308
309 return true
310}
311
312// Equals returns true if the receiver matches the given address.
313//
314// The name of this method is a misnomer, since it doesn't test for exact
315// equality. Instead, it tests that the _specified_ parts of each
316// address match, treating any unspecified parts as wildcards.
317//
318// See also Contains, which takes a more heirarchical approach to comparing
319// addresses.
202func (addr *ResourceAddress) Equals(raw interface{}) bool { 320func (addr *ResourceAddress) Equals(raw interface{}) bool {
203 other, ok := raw.(*ResourceAddress) 321 other, ok := raw.(*ResourceAddress)
204 if !ok { 322 if !ok {
@@ -233,6 +351,58 @@ func (addr *ResourceAddress) Equals(raw interface{}) bool {
233 modeMatch 351 modeMatch
234} 352}
235 353
354// Less returns true if and only if the receiver should be sorted before
355// the given address when presenting a list of resource addresses to
356// an end-user.
357//
358// This sort uses lexicographic sorting for most components, but uses
359// numeric sort for indices, thus causing index 10 to sort after
360// index 9, rather than after index 1.
361func (addr *ResourceAddress) Less(other *ResourceAddress) bool {
362
363 switch {
364
365 case len(addr.Path) < len(other.Path):
366 return true
367
368 case !reflect.DeepEqual(addr.Path, other.Path):
369 // If the two paths are the same length but don't match, we'll just
370 // cheat and compare the string forms since it's easier than
371 // comparing all of the path segments in turn.
372 addrStr := addr.String()
373 otherStr := other.String()
374 return addrStr < otherStr
375
376 case addr.Mode == config.DataResourceMode && other.Mode != config.DataResourceMode:
377 return true
378
379 case addr.Type < other.Type:
380 return true
381
382 case addr.Name < other.Name:
383 return true
384
385 case addr.Index < other.Index:
386 // Since "Index" is -1 for an un-indexed address, this also conveniently
387 // sorts unindexed addresses before indexed ones, should they both
388 // appear for some reason.
389 return true
390
391 case other.InstanceTypeSet && !addr.InstanceTypeSet:
392 return true
393
394 case addr.InstanceType < other.InstanceType:
395 // InstanceType is actually an enum, so this is just an arbitrary
396 // sort based on the enum numeric values, and thus not particularly
397 // meaningful.
398 return true
399
400 default:
401 return false
402
403 }
404}
405
236func ParseResourceIndex(s string) (int, error) { 406func ParseResourceIndex(s string) (int, error) {
237 if s == "" { 407 if s == "" {
238 return -1, nil 408 return -1, nil
@@ -275,7 +445,7 @@ func tokenizeResourceAddress(s string) (map[string]string, error) {
275 // string "aws_instance.web.tainted[1]" 445 // string "aws_instance.web.tainted[1]"
276 re := regexp.MustCompile(`\A` + 446 re := regexp.MustCompile(`\A` +
277 // "module.foo.module.bar" (optional) 447 // "module.foo.module.bar" (optional)
278 `(?P<path>(?:module\.[^.]+\.?)*)` + 448 `(?P<path>(?:module\.(?P<module_name>[^.]+)\.?)*)` +
279 // possibly "data.", if targeting is a data resource 449 // possibly "data.", if targeting is a data resource
280 `(?P<data_prefix>(?:data\.)?)` + 450 `(?P<data_prefix>(?:data\.)?)` +
281 // "aws_instance.web" (optional when module path specified) 451 // "aws_instance.web" (optional when module path specified)
@@ -289,7 +459,7 @@ func tokenizeResourceAddress(s string) (map[string]string, error) {
289 groupNames := re.SubexpNames() 459 groupNames := re.SubexpNames()
290 rawMatches := re.FindAllStringSubmatch(s, -1) 460 rawMatches := re.FindAllStringSubmatch(s, -1)
291 if len(rawMatches) != 1 { 461 if len(rawMatches) != 1 {
292 return nil, fmt.Errorf("Problem parsing address: %q", s) 462 return nil, fmt.Errorf("invalid resource address %q", s)
293 } 463 }
294 464
295 matches := make(map[string]string) 465 matches := make(map[string]string)
diff --git a/vendor/github.com/hashicorp/terraform/terraform/resource_provider.go b/vendor/github.com/hashicorp/terraform/terraform/resource_provider.go
index 1a68c86..7d78f67 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/resource_provider.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/resource_provider.go
@@ -1,5 +1,12 @@
1package terraform 1package terraform
2 2
3import (
4 "fmt"
5
6 multierror "github.com/hashicorp/go-multierror"
7 "github.com/hashicorp/terraform/plugin/discovery"
8)
9
3// ResourceProvider is an interface that must be implemented by any 10// ResourceProvider is an interface that must be implemented by any
4// resource provider: the thing that creates and manages the resources in 11// resource provider: the thing that creates and manages the resources in
5// a Terraform configuration. 12// a Terraform configuration.
@@ -154,6 +161,18 @@ type ResourceProvider interface {
154 ReadDataApply(*InstanceInfo, *InstanceDiff) (*InstanceState, error) 161 ReadDataApply(*InstanceInfo, *InstanceDiff) (*InstanceState, error)
155} 162}
156 163
164// ResourceProviderError may be returned when creating a Context if the
165// required providers cannot be satisfied. This error can then be used to
166// format a more useful message for the user.
167type ResourceProviderError struct {
168 Errors []error
169}
170
171func (e *ResourceProviderError) Error() string {
172 // use multierror to format the default output
173 return multierror.Append(nil, e.Errors...).Error()
174}
175
157// ResourceProviderCloser is an interface that providers that can close 176// ResourceProviderCloser is an interface that providers that can close
158// connections that aren't needed anymore must implement. 177// connections that aren't needed anymore must implement.
159type ResourceProviderCloser interface { 178type ResourceProviderCloser interface {
@@ -171,6 +190,50 @@ type DataSource struct {
171 Name string 190 Name string
172} 191}
173 192
193// ResourceProviderResolver is an interface implemented by objects that are
194// able to resolve a given set of resource provider version constraints
195// into ResourceProviderFactory callbacks.
196type ResourceProviderResolver interface {
197 // Given a constraint map, return a ResourceProviderFactory for each
198 // requested provider. If some or all of the constraints cannot be
199 // satisfied, return a non-nil slice of errors describing the problems.
200 ResolveProviders(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error)
201}
202
203// ResourceProviderResolverFunc wraps a callback function and turns it into
204// a ResourceProviderResolver implementation, for convenience in situations
205// where a function and its associated closure are sufficient as a resolver
206// implementation.
207type ResourceProviderResolverFunc func(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error)
208
209// ResolveProviders implements ResourceProviderResolver by calling the
210// wrapped function.
211func (f ResourceProviderResolverFunc) ResolveProviders(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error) {
212 return f(reqd)
213}
214
215// ResourceProviderResolverFixed returns a ResourceProviderResolver that
216// has a fixed set of provider factories provided by the caller. The returned
217// resolver ignores version constraints entirely and just returns the given
218// factory for each requested provider name.
219//
220// This function is primarily used in tests, to provide mock providers or
221// in-process providers under test.
222func ResourceProviderResolverFixed(factories map[string]ResourceProviderFactory) ResourceProviderResolver {
223 return ResourceProviderResolverFunc(func(reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, []error) {
224 ret := make(map[string]ResourceProviderFactory, len(reqd))
225 var errs []error
226 for name := range reqd {
227 if factory, exists := factories[name]; exists {
228 ret[name] = factory
229 } else {
230 errs = append(errs, fmt.Errorf("provider %q is not available", name))
231 }
232 }
233 return ret, errs
234 })
235}
236
174// ResourceProviderFactory is a function type that creates a new instance 237// ResourceProviderFactory is a function type that creates a new instance
175// of a resource provider. 238// of a resource provider.
176type ResourceProviderFactory func() (ResourceProvider, error) 239type ResourceProviderFactory func() (ResourceProvider, error)
@@ -202,3 +265,21 @@ func ProviderHasDataSource(p ResourceProvider, n string) bool {
202 265
203 return false 266 return false
204} 267}
268
269// resourceProviderFactories matches available plugins to the given version
270// requirements to produce a map of compatible provider plugins if possible,
271// or an error if the currently-available plugins are insufficient.
272//
273// This should be called only with configurations that have passed calls
274// to config.Validate(), which ensures that all of the given version
275// constraints are valid. It will panic if any invalid constraints are present.
276func resourceProviderFactories(resolver ResourceProviderResolver, reqd discovery.PluginRequirements) (map[string]ResourceProviderFactory, error) {
277 ret, errs := resolver.ResolveProviders(reqd)
278 if errs != nil {
279 return nil, &ResourceProviderError{
280 Errors: errs,
281 }
282 }
283
284 return ret, nil
285}
diff --git a/vendor/github.com/hashicorp/terraform/terraform/state.go b/vendor/github.com/hashicorp/terraform/terraform/state.go
index 074b682..0c46194 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/state.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/state.go
@@ -533,6 +533,43 @@ func (s *State) equal(other *State) bool {
533 return true 533 return true
534} 534}
535 535
536// MarshalEqual is similar to Equal but provides a stronger definition of
537// "equal", where two states are equal if and only if their serialized form
538// is byte-for-byte identical.
539//
540// This is primarily useful for callers that are trying to save snapshots
541// of state to persistent storage, allowing them to detect when a new
542// snapshot must be taken.
543//
544// Note that the serial number and lineage are included in the serialized form,
545// so it's the caller's responsibility to properly manage these attributes
546// so that this method is only called on two states that have the same
547// serial and lineage, unless detecting such differences is desired.
548func (s *State) MarshalEqual(other *State) bool {
549 if s == nil && other == nil {
550 return true
551 } else if s == nil || other == nil {
552 return false
553 }
554
555 recvBuf := &bytes.Buffer{}
556 otherBuf := &bytes.Buffer{}
557
558 err := WriteState(s, recvBuf)
559 if err != nil {
560 // should never happen, since we're writing to a buffer
561 panic(err)
562 }
563
564 err = WriteState(other, otherBuf)
565 if err != nil {
566 // should never happen, since we're writing to a buffer
567 panic(err)
568 }
569
570 return bytes.Equal(recvBuf.Bytes(), otherBuf.Bytes())
571}
572
536type StateAgeComparison int 573type StateAgeComparison int
537 574
538const ( 575const (
@@ -603,6 +640,10 @@ func (s *State) SameLineage(other *State) bool {
603// DeepCopy performs a deep copy of the state structure and returns 640// DeepCopy performs a deep copy of the state structure and returns
604// a new structure. 641// a new structure.
605func (s *State) DeepCopy() *State { 642func (s *State) DeepCopy() *State {
643 if s == nil {
644 return nil
645 }
646
606 copy, err := copystructure.Config{Lock: true}.Copy(s) 647 copy, err := copystructure.Config{Lock: true}.Copy(s)
607 if err != nil { 648 if err != nil {
608 panic(err) 649 panic(err)
@@ -611,30 +652,6 @@ func (s *State) DeepCopy() *State {
611 return copy.(*State) 652 return copy.(*State)
612} 653}
613 654
614// IncrementSerialMaybe increments the serial number of this state
615// if it different from the other state.
616func (s *State) IncrementSerialMaybe(other *State) {
617 if s == nil {
618 return
619 }
620 if other == nil {
621 return
622 }
623 s.Lock()
624 defer s.Unlock()
625
626 if s.Serial > other.Serial {
627 return
628 }
629 if other.TFVersion != s.TFVersion || !s.equal(other) {
630 if other.Serial > s.Serial {
631 s.Serial = other.Serial
632 }
633
634 s.Serial++
635 }
636}
637
638// FromFutureTerraform checks if this state was written by a Terraform 655// FromFutureTerraform checks if this state was written by a Terraform
639// version from the future. 656// version from the future.
640func (s *State) FromFutureTerraform() bool { 657func (s *State) FromFutureTerraform() bool {
@@ -660,6 +677,7 @@ func (s *State) init() {
660 if s.Version == 0 { 677 if s.Version == 0 {
661 s.Version = StateVersion 678 s.Version = StateVersion
662 } 679 }
680
663 if s.moduleByPath(rootModulePath) == nil { 681 if s.moduleByPath(rootModulePath) == nil {
664 s.addModule(rootModulePath) 682 s.addModule(rootModulePath)
665 } 683 }
diff --git a/vendor/github.com/hashicorp/terraform/terraform/test_failure b/vendor/github.com/hashicorp/terraform/terraform/test_failure
new file mode 100644
index 0000000..5d3ad1a
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/terraform/test_failure
@@ -0,0 +1,9 @@
1--- FAIL: TestContext2Plan_moduleProviderInherit (0.01s)
2 context_plan_test.go:552: bad: []string{"child"}
3map[string]dag.Vertex{}
4"module.middle.null"
5map[string]dag.Vertex{}
6"module.middle.module.inner.null"
7map[string]dag.Vertex{}
8"aws"
9FAIL
diff --git a/vendor/github.com/hashicorp/terraform/terraform/transform_resource_refresh_plannable.go b/vendor/github.com/hashicorp/terraform/terraform/transform_resource_refresh_plannable.go
deleted file mode 100644
index 35358a3..0000000
--- a/vendor/github.com/hashicorp/terraform/terraform/transform_resource_refresh_plannable.go
+++ /dev/null
@@ -1,55 +0,0 @@
1package terraform
2
3import (
4 "fmt"
5 "log"
6)
7
8// ResourceRefreshPlannableTransformer is a GraphTransformer that replaces any
9// nodes that don't have state yet exist in config with
10// NodePlannableResourceInstance.
11//
12// This transformer is used when expanding count on managed resource nodes
13// during the refresh phase to ensure that data sources that have
14// interpolations that depend on resources existing in the graph can be walked
15// properly.
16type ResourceRefreshPlannableTransformer struct {
17 // The full global state.
18 State *State
19}
20
21// Transform implements GraphTransformer for
22// ResourceRefreshPlannableTransformer.
23func (t *ResourceRefreshPlannableTransformer) Transform(g *Graph) error {
24nextVertex:
25 for _, v := range g.Vertices() {
26 addr := v.(*NodeRefreshableManagedResourceInstance).Addr
27
28 // Find the state for this address, if there is one
29 filter := &StateFilter{State: t.State}
30 results, err := filter.Filter(addr.String())
31 if err != nil {
32 return err
33 }
34
35 // Check to see if we have a state for this resource. If we do, skip this
36 // node.
37 for _, result := range results {
38 if _, ok := result.Value.(*ResourceState); ok {
39 continue nextVertex
40 }
41 }
42 // If we don't, convert this resource to a NodePlannableResourceInstance node
43 // with all of the data we need to make it happen.
44 log.Printf("[TRACE] No state for %s, converting to NodePlannableResourceInstance", addr.String())
45 new := &NodePlannableResourceInstance{
46 NodeAbstractResource: v.(*NodeRefreshableManagedResourceInstance).NodeAbstractResource,
47 }
48 // Replace the node in the graph
49 if !g.Replace(v, new) {
50 return fmt.Errorf("ResourceRefreshPlannableTransformer: Could not replace node %#v with %#v", v, new)
51 }
52 }
53
54 return nil
55}
diff --git a/vendor/github.com/hashicorp/terraform/terraform/transform_targets.go b/vendor/github.com/hashicorp/terraform/terraform/transform_targets.go
index 125f9e3..4f117b4 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/transform_targets.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/transform_targets.go
@@ -41,6 +41,12 @@ type TargetsTransformer struct {
41 // that already have the targets parsed 41 // that already have the targets parsed
42 ParsedTargets []ResourceAddress 42 ParsedTargets []ResourceAddress
43 43
44 // If set, the index portions of resource addresses will be ignored
45 // for comparison. This is used when transforming a graph where
46 // counted resources have not yet been expanded, since otherwise
47 // the unexpanded nodes (which never have indices) would not match.
48 IgnoreIndices bool
49
44 // Set to true when we're in a `terraform destroy` or a 50 // Set to true when we're in a `terraform destroy` or a
45 // `terraform plan -destroy` 51 // `terraform plan -destroy`
46 Destroy bool 52 Destroy bool
@@ -199,7 +205,12 @@ func (t *TargetsTransformer) nodeIsTarget(
199 205
200 addr := r.ResourceAddr() 206 addr := r.ResourceAddr()
201 for _, targetAddr := range addrs { 207 for _, targetAddr := range addrs {
202 if targetAddr.Equals(addr) { 208 if t.IgnoreIndices {
209 // targetAddr is not a pointer, so we can safely mutate it without
210 // interfering with references elsewhere.
211 targetAddr.Index = -1
212 }
213 if targetAddr.Contains(addr) {
203 return true 214 return true
204 } 215 }
205 } 216 }
diff --git a/vendor/github.com/hashicorp/terraform/terraform/util.go b/vendor/github.com/hashicorp/terraform/terraform/util.go
index f41f0d7..752241a 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/util.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/util.go
@@ -2,7 +2,8 @@ package terraform
2 2
3import ( 3import (
4 "sort" 4 "sort"
5 "strings" 5
6 "github.com/hashicorp/terraform/config"
6) 7)
7 8
8// Semaphore is a wrapper around a channel to provide 9// Semaphore is a wrapper around a channel to provide
@@ -47,21 +48,8 @@ func (s Semaphore) Release() {
47 } 48 }
48} 49}
49 50
50// resourceProvider returns the provider name for the given type. 51func resourceProvider(resourceType, explicitProvider string) string {
51func resourceProvider(t, alias string) string { 52 return config.ResourceProviderFullName(resourceType, explicitProvider)
52 if alias != "" {
53 return alias
54 }
55
56 idx := strings.IndexRune(t, '_')
57 if idx == -1 {
58 // If no underscores, the resource name is assumed to be
59 // also the provider name, e.g. if the provider exposes
60 // only a single resource of each type.
61 return t
62 }
63
64 return t[:idx]
65} 53}
66 54
67// strSliceContains checks if a given string is contained in a slice 55// strSliceContains checks if a given string is contained in a slice
diff --git a/vendor/github.com/hashicorp/terraform/terraform/version.go b/vendor/github.com/hashicorp/terraform/terraform/version.go
index cdfb8fb..d61b11e 100644
--- a/vendor/github.com/hashicorp/terraform/terraform/version.go
+++ b/vendor/github.com/hashicorp/terraform/terraform/version.go
@@ -7,12 +7,12 @@ import (
7) 7)
8 8
9// The main version number that is being run at the moment. 9// The main version number that is being run at the moment.
10const Version = "0.9.8" 10const Version = "0.10.0"
11 11
12// A pre-release marker for the version. If this is "" (empty string) 12// A pre-release marker for the version. If this is "" (empty string)
13// then it means that it is a final release. Otherwise, this is a pre-release 13// then it means that it is a final release. Otherwise, this is a pre-release
14// such as "dev" (in development), "beta", "rc1", etc. 14// such as "dev" (in development), "beta", "rc1", etc.
15var VersionPrerelease = "" 15var VersionPrerelease = "dev"
16 16
17// SemVersion is an instance of version.Version. This has the secondary 17// SemVersion is an instance of version.Version. This has the secondary
18// benefit of verifying during tests and init time that our version is a 18// benefit of verifying during tests and init time that our version is a