aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/terraform/helper
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper')
-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
8 files changed, 147 insertions, 65 deletions
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 {