From 5a50dc5ccc165bd4df181fb077e864d9e13f3619 Mon Sep 17 00:00:00 2001 From: kt Date: Wed, 17 Apr 2019 14:30:10 -0700 Subject: [PATCH] go get github.com/hashicorp/terraform@pluginsdk-v0.12-early8; go mod tidy; go mod vendor; --- go.mod | 2 +- go.sum | 11 +++-- vendor/github.com/hashicorp/hcl2/hcl/ops.go | 22 +++++++++ vendor/github.com/hashicorp/hcl2/hcl/pos.go | 3 ++ .../hashicorp/hcl2/hcl/pos_scanner.go | 18 ++++--- .../terraform/configs/module_merge_body.go | 26 +++++++--- .../hashicorp/terraform/configs/util.go | 18 +++++++ .../helper/resource/testing_import_state.go | 41 +++++++++++++++- .../terraform/helper/schema/field_reader.go | 8 +++ .../terraform/helper/schema/resource.go | 7 +++ .../terraform/helper/schema/schema.go | 3 +- .../terraform/helper/schema/shims.go | 8 +-- .../terraform/lang/funcs/collection.go | 49 +++++++++++++++++++ .../hashicorp/terraform/lang/functions.go | 2 +- .../terraform/states/instance_object.go | 2 +- .../hashicorp/terraform/terraform/diff.go | 44 ++++++++++++++++- .../terraform/terraform/eval_apply.go | 10 ++-- .../hashicorp/terraform/terraform/evaluate.go | 17 +++++++ vendor/modules.txt | 4 +- 19 files changed, 260 insertions(+), 35 deletions(-) diff --git a/go.mod b/go.mod index f0e6177604cc..863d7a81479e 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/hashicorp/go-getter v1.1.0 github.com/hashicorp/go-multierror v1.0.0 github.com/hashicorp/go-uuid v1.0.1 - github.com/hashicorp/terraform v0.12.0-alpha4.0.20190410234817-9e158400c228 + github.com/hashicorp/terraform v0.12.0-alpha4.0.20190417210818-177a7afb781f github.com/satori/go.uuid v1.2.0 github.com/satori/uuid v0.0.0-20160927100844-b061729afc07 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 diff --git a/go.sum b/go.sum index 1de45007d7e7..dc57b8340097 100644 --- a/go.sum +++ b/go.sum @@ -140,6 +140,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmg github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.5.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/hashicorp/aws-sdk-go-base v0.2.0 h1:5bjZnWCvQg9Im5CHZr9t90IaFC4uvVlMl2fTh23IoCk= github.com/hashicorp/aws-sdk-go-base v0.2.0/go.mod h1:ZIWACGGi0N7a4DZbf15yuE1JQORmWLtBcVM6F5SXNFU= github.com/hashicorp/consul v0.0.0-20171026175957-610f3c86a089 h1:1eDpXAxTh0iPv+1kc9/gfSI2pxRERDsTk/lNGolwHn8= github.com/hashicorp/consul v0.0.0-20171026175957-610f3c86a089/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI= @@ -185,16 +186,17 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws= github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/hashicorp/hcl2 v0.0.0-20181208003705-670926858200/go.mod h1:ShfpTh661oAaxo7VcNxg0zcZW6jvMa7Moy2oFx7e5dE= -github.com/hashicorp/hcl2 v0.0.0-20190402200843-8b450a7d58f9 h1:zCITwiA0cog6aYr/a/McDHKtgsEpYxXvTIgugv5iu8o= -github.com/hashicorp/hcl2 v0.0.0-20190402200843-8b450a7d58f9/go.mod h1:HtEzazM5AZ9fviNEof8QZB4T1Vz9UhHrGhnMPzl//Ek= +github.com/hashicorp/hcl2 v0.0.0-20190416162332-2c5a4b7d729a h1:doKt9ZBCYgYQrGK6CqJsEB+8xqm3WoFyKu4TPZlyymg= +github.com/hashicorp/hcl2 v0.0.0-20190416162332-2c5a4b7d729a/go.mod h1:HtEzazM5AZ9fviNEof8QZB4T1Vz9UhHrGhnMPzl//Ek= github.com/hashicorp/hil v0.0.0-20190212112733-ab17b08d6590 h1:2yzhWGdgQUWZUCNK+AoO35V+HTsgEmcM4J9IkArh7PI= github.com/hashicorp/hil v0.0.0-20190212112733-ab17b08d6590/go.mod h1:n2TSygSNwsLJ76m8qFXTSc7beTb+auJxYdqrnoqwZWE= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE= +github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb h1:ZbgmOQt8DOg796figP87/EFCVx2v2h9yRvwHF/zceX4= github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= -github.com/hashicorp/terraform v0.12.0-alpha4.0.20190410234817-9e158400c228 h1:lOMGZhCqdE5Vckpn/T0CX2r+Pv20MifE5R2cZGTRLFA= -github.com/hashicorp/terraform v0.12.0-alpha4.0.20190410234817-9e158400c228/go.mod h1:aqon1YWM8WlqN05YI2PPpXH4K8QzGgSfpyPuTpRJ9VI= +github.com/hashicorp/terraform v0.12.0-alpha4.0.20190417210818-177a7afb781f h1:Gl7Ig3E2XpntOCaGMZrMR9zSfNJl4JXHiqP64zJCzak= +github.com/hashicorp/terraform v0.12.0-alpha4.0.20190417210818-177a7afb781f/go.mod h1:A3NsI7WT87OMgpcD15cu6dK2YNpihchZp5fxUf8EHBg= github.com/hashicorp/terraform-config-inspect v0.0.0-20190327195015-8022a2663a70 h1:oZm5nE11yhzsTRz/YrUyDMSvixePqjoZihwn8ipuOYI= github.com/hashicorp/terraform-config-inspect v0.0.0-20190327195015-8022a2663a70/go.mod h1:ItvqtvbC3K23FFET62ZwnkwtpbKZm8t8eMcWjmVVjD8= github.com/hashicorp/vault v0.10.4/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0= @@ -288,6 +290,7 @@ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm github.com/packer-community/winrmcp v0.0.0-20180102160824-81144009af58 h1:m3CEgv3ah1Rhy82L+c0QG/U3VyY1UsvsIdkh0/rU97Y= github.com/packer-community/winrmcp v0.0.0-20180102160824-81144009af58/go.mod h1:f6Izs6JvFTdnRbziASagjZ2vmf55NSIkC/weStxCHqk= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pkg/errors v0.0.0-20170505043639-c605e284fe17 h1:chPfVn+gpAM5CTpTyVU9j8J+xgRGwmoDlNDLjKnJiYo= github.com/pkg/errors v0.0.0-20170505043639-c605e284fe17/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/vendor/github.com/hashicorp/hcl2/hcl/ops.go b/vendor/github.com/hashicorp/hcl2/hcl/ops.go index 3aa0bdf04e49..5d2910c13010 100644 --- a/vendor/github.com/hashicorp/hcl2/hcl/ops.go +++ b/vendor/github.com/hashicorp/hcl2/hcl/ops.go @@ -2,6 +2,7 @@ package hcl import ( "fmt" + "math/big" "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/convert" @@ -84,6 +85,27 @@ func Index(collection, key cty.Value, srcRange *Range) (cty.Value, Diagnostics) } } if has.False() { + // We have a more specialized error message for the situation of + // using a fractional number to index into a sequence, because + // that will tend to happen if the user is trying to use division + // to calculate an index and not realizing that HCL does float + // division rather than integer division. + if (ty.IsListType() || ty.IsTupleType()) && key.Type().Equals(cty.Number) { + if key.IsKnown() && !key.IsNull() { + bf := key.AsBigFloat() + if _, acc := bf.Int(nil); acc != big.Exact { + return cty.DynamicVal, Diagnostics{ + { + Severity: DiagError, + Summary: "Invalid index", + Detail: fmt.Sprintf("The given key does not identify an element in this collection value: indexing a sequence requires a whole number, but the given index (%g) has a fractional part.", bf), + Subject: srcRange, + }, + } + } + } + } + return cty.DynamicVal, Diagnostics{ { Severity: DiagError, diff --git a/vendor/github.com/hashicorp/hcl2/hcl/pos.go b/vendor/github.com/hashicorp/hcl2/hcl/pos.go index 6b7ec1d34748..06db8bfbd4f8 100644 --- a/vendor/github.com/hashicorp/hcl2/hcl/pos.go +++ b/vendor/github.com/hashicorp/hcl2/hcl/pos.go @@ -31,6 +31,9 @@ type Pos struct { Byte int } +// InitialPos is a suitable position to use to mark the start of a file. +var InitialPos = Pos{Byte: 0, Line: 1, Column: 1} + // Range represents a span of characters between two positions in a source // file. // diff --git a/vendor/github.com/hashicorp/hcl2/hcl/pos_scanner.go b/vendor/github.com/hashicorp/hcl2/hcl/pos_scanner.go index 7c8f2dfa5826..17c0d7c6b1e1 100644 --- a/vendor/github.com/hashicorp/hcl2/hcl/pos_scanner.go +++ b/vendor/github.com/hashicorp/hcl2/hcl/pos_scanner.go @@ -29,8 +29,8 @@ type RangeScanner struct { err error // error from last scan, if any } -// Create a new RangeScanner for the given buffer, producing ranges for the -// given filename. +// NewRangeScanner creates a new RangeScanner for the given buffer, producing +// ranges for the given filename. // // Since ranges have grapheme-cluster granularity rather than byte granularity, // the scanner will produce incorrect results if the given SplitFunc creates @@ -39,15 +39,19 @@ type RangeScanner struct { // around individual UTF-8 sequences, which will split any multi-sequence // grapheme clusters. func NewRangeScanner(b []byte, filename string, cb bufio.SplitFunc) *RangeScanner { + return NewRangeScannerFragment(b, filename, InitialPos, cb) +} + +// NewRangeScannerFragment is like NewRangeScanner but the ranges it produces +// will be offset by the given starting position, which is appropriate for +// sub-slices of a file, whereas NewRangeScanner assumes it is scanning an +// entire file. +func NewRangeScannerFragment(b []byte, filename string, start Pos, cb bufio.SplitFunc) *RangeScanner { return &RangeScanner{ filename: filename, b: b, cb: cb, - pos: Pos{ - Byte: 0, - Line: 1, - Column: 1, - }, + pos: start, } } diff --git a/vendor/github.com/hashicorp/terraform/configs/module_merge_body.go b/vendor/github.com/hashicorp/terraform/configs/module_merge_body.go index bb40e268315f..0ed561eeee4e 100644 --- a/vendor/github.com/hashicorp/terraform/configs/module_merge_body.go +++ b/vendor/github.com/hashicorp/terraform/configs/module_merge_body.go @@ -40,11 +40,12 @@ var _ hcl.Body = mergeBody{} func (b mergeBody) Content(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Diagnostics) { var diags hcl.Diagnostics - oSchema := schemaForOverrides(schema) + baseSchema := schemaWithDynamic(schema) + overrideSchema := schemaWithDynamic(schemaForOverrides(schema)) - baseContent, cDiags := b.Base.Content(schema) + baseContent, _, cDiags := b.Base.PartialContent(baseSchema) diags = append(diags, cDiags...) - overrideContent, cDiags := b.Override.Content(oSchema) + overrideContent, _, cDiags := b.Override.PartialContent(overrideSchema) diags = append(diags, cDiags...) content := b.prepareContent(baseContent, overrideContent) @@ -54,11 +55,12 @@ func (b mergeBody) Content(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Diagno func (b mergeBody) PartialContent(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Body, hcl.Diagnostics) { var diags hcl.Diagnostics - oSchema := schemaForOverrides(schema) + baseSchema := schemaWithDynamic(schema) + overrideSchema := schemaWithDynamic(schemaForOverrides(schema)) - baseContent, baseRemain, cDiags := b.Base.PartialContent(schema) + baseContent, baseRemain, cDiags := b.Base.PartialContent(baseSchema) diags = append(diags, cDiags...) - overrideContent, overrideRemain, cDiags := b.Override.PartialContent(oSchema) + overrideContent, overrideRemain, cDiags := b.Override.PartialContent(overrideSchema) diags = append(diags, cDiags...) content := b.prepareContent(baseContent, overrideContent) @@ -90,9 +92,21 @@ func (b mergeBody) prepareContent(base *hcl.BodyContent, override *hcl.BodyConte overriddenBlockTypes := make(map[string]bool) for _, block := range override.Blocks { + if block.Type == "dynamic" { + overriddenBlockTypes[block.Labels[0]] = true + continue + } overriddenBlockTypes[block.Type] = true } for _, block := range base.Blocks { + // We skip over dynamic blocks whose type label is an overridden type + // but note that below we do still leave them as dynamic blocks in + // the result because expanding the dynamic blocks that are left is + // done much later during the core graph walks, where we can safely + // evaluate the expressions. + if block.Type == "dynamic" && overriddenBlockTypes[block.Labels[0]] { + continue + } if overriddenBlockTypes[block.Type] { continue } diff --git a/vendor/github.com/hashicorp/terraform/configs/util.go b/vendor/github.com/hashicorp/terraform/configs/util.go index 002bb8cb84b9..5fbde43109a4 100644 --- a/vendor/github.com/hashicorp/terraform/configs/util.go +++ b/vendor/github.com/hashicorp/terraform/configs/util.go @@ -43,3 +43,21 @@ func schemaForOverrides(schema *hcl.BodySchema) *hcl.BodySchema { return ret } + +// schemaWithDynamic takes a *hcl.BodySchema and produces a new one that +// is equivalent except that it accepts an additional block type "dynamic" with +// a single label, used to recognize usage of the HCL dynamic block extension. +func schemaWithDynamic(schema *hcl.BodySchema) *hcl.BodySchema { + ret := &hcl.BodySchema{ + Attributes: schema.Attributes, + Blocks: make([]hcl.BlockHeaderSchema, len(schema.Blocks), len(schema.Blocks)+1), + } + + copy(ret.Blocks, schema.Blocks) + ret.Blocks = append(ret.Blocks, hcl.BlockHeaderSchema{ + Type: "dynamic", + LabelNames: []string{"type"}, + }) + + return ret +} diff --git a/vendor/github.com/hashicorp/terraform/helper/resource/testing_import_state.go b/vendor/github.com/hashicorp/terraform/helper/resource/testing_import_state.go index 97a69c594174..e1b7aea81a35 100644 --- a/vendor/github.com/hashicorp/terraform/helper/resource/testing_import_state.go +++ b/vendor/github.com/hashicorp/terraform/helper/resource/testing_import_state.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/hcl2/hcl/hclsyntax" "github.com/hashicorp/terraform/addrs" + "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/states" "github.com/hashicorp/terraform/terraform" ) @@ -130,6 +131,21 @@ func testStepImportState( r.Primary.ID) } + // We'll try our best to find the schema for this resource type + // so we can ignore Removed fields during validation. If we fail + // to find the schema then we won't ignore them and so the test + // will need to rely on explicit ImportStateVerifyIgnore, though + // this shouldn't happen in any reasonable case. + var rsrcSchema *schema.Resource + if providerAddr, diags := addrs.ParseAbsProviderConfigStr(r.Provider); !diags.HasErrors() { + providerType := providerAddr.ProviderConfig.Type + if provider, ok := step.providers[providerType]; ok { + if provider, ok := provider.(*schema.Provider); ok { + rsrcSchema = provider.ResourcesMap[r.Type] + } + } + } + // don't add empty flatmapped containers, so we can more easily // compare the attributes skipEmpty := func(k, v string) bool { @@ -160,18 +176,39 @@ func testStepImportState( // Remove fields we're ignoring for _, v := range step.ImportStateVerifyIgnore { - for k, _ := range actual { + for k := range actual { if strings.HasPrefix(k, v) { delete(actual, k) } } - for k, _ := range expected { + for k := range expected { if strings.HasPrefix(k, v) { delete(expected, k) } } } + // Also remove any attributes that are marked as "Removed" in the + // schema, if we have a schema to check that against. + if rsrcSchema != nil { + for k := range actual { + for _, schema := range rsrcSchema.SchemasForFlatmapPath(k) { + if schema.Removed != "" { + delete(actual, k) + break + } + } + } + for k := range expected { + for _, schema := range rsrcSchema.SchemasForFlatmapPath(k) { + if schema.Removed != "" { + delete(expected, k) + break + } + } + } + } + if !reflect.DeepEqual(actual, expected) { // Determine only the different attributes for k, v := range expected { diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/field_reader.go b/vendor/github.com/hashicorp/terraform/helper/schema/field_reader.go index b80b223a2954..2a66a068fb6e 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/field_reader.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/field_reader.go @@ -3,6 +3,7 @@ package schema import ( "fmt" "strconv" + "strings" ) // FieldReaders are responsible for decoding fields out of data into @@ -41,6 +42,13 @@ func (r *FieldReadResult) ValueOrZero(s *Schema) interface{} { return s.ZeroValue() } +// SchemasForFlatmapPath tries its best to find a sequence of schemas that +// the given dot-delimited attribute path traverses through. +func SchemasForFlatmapPath(path string, schemaMap map[string]*Schema) []*Schema { + parts := strings.Split(path, ".") + return addrToSchema(parts, schemaMap) +} + // addrToSchema finds the final element schema for the given address // and the given schema. It returns all the schemas that led to the final // schema. These are in order of the address (out to in). diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/resource.go b/vendor/github.com/hashicorp/terraform/helper/schema/resource.go index d96bbcfde2a0..b5e306574555 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/resource.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/resource.go @@ -754,6 +754,13 @@ func (r *Resource) TestResourceData() *ResourceData { } } +// SchemasForFlatmapPath tries its best to find a sequence of schemas that +// the given dot-delimited attribute path traverses through in the schema +// of the receiving Resource. +func (r *Resource) SchemasForFlatmapPath(path string) []*Schema { + return SchemasForFlatmapPath(path, r.Schema) +} + // Returns true if the resource is "top level" i.e. not a sub-resource. func (r *Resource) isTopLevel() bool { // TODO: This is a heuristic; replace with a definitive attribute? diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/schema.go b/vendor/github.com/hashicorp/terraform/helper/schema/schema.go index 56f2930fce0d..8cb9bc9f9de5 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/schema.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/schema.go @@ -266,7 +266,8 @@ type Schema struct { // guaranteed to be of the proper Schema type, and it can yield warnings or // errors based on inspection of that value. // - // ValidateFunc currently only works for primitive types. + // ValidateFunc is honored only when the schema's Type is set to TypeInt, + // TypeFloat, TypeString, TypeBool, or TypeMap. It is ignored for all other types. ValidateFunc SchemaValidateFunc // Sensitive ensures that the attribute's value does not get displayed in diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/shims.go b/vendor/github.com/hashicorp/terraform/helper/schema/shims.go index e66fc09d450d..dc840204b9c1 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/shims.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/shims.go @@ -133,9 +133,10 @@ func LegacyResourceSchema(r *Resource) *Resource { return newResource } -// LegacySchema takes a *Schema and returns a deep copy with 0.12 specific -// features removed. This is used by the shims to get a configschema that -// directly matches the structure of the schema.Resource. +// LegacySchema takes a *Schema and returns a deep copy with some 0.12-specific +// features disabled. This is used by the shims to get a configschema that +// better reflects the given schema.Resource, without any adjustments we +// make for when sending a schema to Terraform Core. func LegacySchema(s *Schema) *Schema { if s == nil { return nil @@ -143,7 +144,6 @@ func LegacySchema(s *Schema) *Schema { // start with a shallow copy newSchema := new(Schema) *newSchema = *s - newSchema.ConfigMode = SchemaConfigModeAuto newSchema.SkipCoreTypeCheck = false switch e := newSchema.Elem.(type) { diff --git a/vendor/github.com/hashicorp/terraform/lang/funcs/collection.go b/vendor/github.com/hashicorp/terraform/lang/funcs/collection.go index 23b9754652d2..f85bfae2f549 100644 --- a/vendor/github.com/hashicorp/terraform/lang/funcs/collection.go +++ b/vendor/github.com/hashicorp/terraform/lang/funcs/collection.go @@ -119,6 +119,50 @@ var LengthFunc = function.New(&function.Spec{ }, }) +// CoalesceFunc contructs a function that takes any number of arguments and +// returns the first one that isn't empty. This function was copied from go-cty +// stdlib and modified so that it returns the first *non-empty* non-null element +// from a sequence, instead of merely the first non-null. +var CoalesceFunc = function.New(&function.Spec{ + Params: []function.Parameter{}, + VarParam: &function.Parameter{ + Name: "vals", + Type: cty.DynamicPseudoType, + AllowUnknown: true, + AllowDynamicType: true, + AllowNull: true, + }, + Type: func(args []cty.Value) (ret cty.Type, err error) { + argTypes := make([]cty.Type, len(args)) + for i, val := range args { + argTypes[i] = val.Type() + } + retType, _ := convert.UnifyUnsafe(argTypes) + if retType == cty.NilType { + return cty.NilType, fmt.Errorf("all arguments must have the same type") + } + return retType, nil + }, + Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { + for _, argVal := range args { + // We already know this will succeed because of the checks in our Type func above + argVal, _ = convert.Convert(argVal, retType) + if !argVal.IsKnown() { + return cty.UnknownVal(retType), nil + } + if argVal.IsNull() { + continue + } + if retType == cty.String && argVal.RawEquals(cty.StringVal("")) { + continue + } + + return argVal, nil + } + return cty.NilVal, fmt.Errorf("no non-null, non-empty-string arguments") + }, +}) + // CoalesceListFunc contructs a function that takes any number of list arguments // and returns the first one that isn't empty. var CoalesceListFunc = function.New(&function.Spec{ @@ -1258,6 +1302,11 @@ func Length(collection cty.Value) (cty.Value, error) { return LengthFunc.Call([]cty.Value{collection}) } +// Coalesce takes any number of arguments and returns the first one that isn't empty. +func Coalesce(args ...cty.Value) (cty.Value, error) { + return CoalesceFunc.Call(args) +} + // CoalesceList takes any number of list arguments and returns the first one that isn't empty. func CoalesceList(args ...cty.Value) (cty.Value, error) { return CoalesceListFunc.Call(args) diff --git a/vendor/github.com/hashicorp/terraform/lang/functions.go b/vendor/github.com/hashicorp/terraform/lang/functions.go index a7a7009381d1..bcda0e2966be 100644 --- a/vendor/github.com/hashicorp/terraform/lang/functions.go +++ b/vendor/github.com/hashicorp/terraform/lang/functions.go @@ -42,7 +42,7 @@ func (s *Scope) Functions() map[string]function.Function { "cidrhost": funcs.CidrHostFunc, "cidrnetmask": funcs.CidrNetmaskFunc, "cidrsubnet": funcs.CidrSubnetFunc, - "coalesce": stdlib.CoalesceFunc, + "coalesce": funcs.CoalesceFunc, "coalescelist": funcs.CoalesceListFunc, "compact": funcs.CompactFunc, "concat": stdlib.ConcatFunc, diff --git a/vendor/github.com/hashicorp/terraform/states/instance_object.go b/vendor/github.com/hashicorp/terraform/states/instance_object.go index b45bfa6ac5c8..1374c59d385e 100644 --- a/vendor/github.com/hashicorp/terraform/states/instance_object.go +++ b/vendor/github.com/hashicorp/terraform/states/instance_object.go @@ -19,7 +19,7 @@ type ResourceInstanceObject struct { // Terraform. Value cty.Value - // Internal is an opaque value set by the provider when this object was + // Private is an opaque value set by the provider when this object was // last created or updated. Terraform Core does not use this value in // any way and it is not exposed anywhere in the user interface, so // a provider can use it for retaining any necessary private state. diff --git a/vendor/github.com/hashicorp/terraform/terraform/diff.go b/vendor/github.com/hashicorp/terraform/terraform/diff.go index 00b0052e9b72..7a6ef3d3282f 100644 --- a/vendor/github.com/hashicorp/terraform/terraform/diff.go +++ b/vendor/github.com/hashicorp/terraform/terraform/diff.go @@ -646,8 +646,10 @@ func (d *InstanceDiff) applyBlockDiff(path []string, attrs map[string]string, sc func (d *InstanceDiff) applyAttrDiff(path []string, attrs map[string]string, attrSchema *configschema.Attribute) (map[string]string, error) { ty := attrSchema.Type switch { - case ty.IsListType(), ty.IsTupleType(), ty.IsMapType(), ty.IsSetType(): + case ty.IsListType(), ty.IsTupleType(), ty.IsMapType(): return d.applyCollectionDiff(path, attrs, attrSchema) + case ty.IsSetType(): + return d.applySetDiff(path, attrs, attrSchema) default: return d.applySingleAttrDiff(path, attrs, attrSchema) } @@ -873,6 +875,46 @@ func (d *InstanceDiff) applyCollectionDiff(path []string, attrs map[string]strin return result, nil } +func (d *InstanceDiff) applySetDiff(path []string, attrs map[string]string, attrSchema *configschema.Attribute) (map[string]string, error) { + // We only need this special behavior for sets of object. + if !attrSchema.Type.ElementType().IsObjectType() { + // The normal collection apply behavior will work okay for this one, then. + return d.applyCollectionDiff(path, attrs, attrSchema) + } + + // When we're dealing with a set of an object type we actually want to + // use our normal _block type_ apply behaviors, so we'll construct ourselves + // a synthetic schema that treats the object type as a block type and + // then delegate to our block apply method. + synthSchema := &configschema.Block{ + Attributes: make(map[string]*configschema.Attribute), + } + + for name, ty := range attrSchema.Type.ElementType().AttributeTypes() { + // We can safely make everything into an attribute here because in the + // event that there are nested set attributes we'll end up back in + // here again recursively and can then deal with the next level of + // expansion. + synthSchema.Attributes[name] = &configschema.Attribute{ + Type: ty, + Optional: true, + } + } + + parentPath := path[:len(path)-1] + childName := path[len(path)-1] + containerSchema := &configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + childName: { + Nesting: configschema.NestingSet, + Block: *synthSchema, + }, + }, + } + + return d.applyBlockDiff(parentPath, attrs, containerSchema) +} + // countFlatmapContainerValues returns the number of values in the flatmapped container // (set, map, list) indexed by key. The key argument is expected to include the // trailing ".#", or ".%". diff --git a/vendor/github.com/hashicorp/terraform/terraform/eval_apply.go b/vendor/github.com/hashicorp/terraform/terraform/eval_apply.go index 1d766cda8fed..09313f7fc8b6 100644 --- a/vendor/github.com/hashicorp/terraform/terraform/eval_apply.go +++ b/vendor/github.com/hashicorp/terraform/terraform/eval_apply.go @@ -247,11 +247,11 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) { } // Sometimes providers return a null value when an operation fails for some - // reason, but for any action other than delete we'd rather keep the prior - // state so that the error can be corrected on a subsequent run. We must - // only do this for null new value though, or else we may discard partial - // updates the provider was able to complete. - if change.Action != plans.Delete && diags.HasErrors() && newVal.IsNull() { + // reason, but we'd rather keep the prior state so that the error can be + // corrected on a subsequent run. We must only do this for null new value + // though, or else we may discard partial updates the provider was able to + // complete. + if diags.HasErrors() && newVal.IsNull() { // Otherwise, we'll continue but using the prior state as the new value, // making this effectively a no-op. If the item really _has_ been // deleted then our next refresh will detect that and fix it up. diff --git a/vendor/github.com/hashicorp/terraform/terraform/evaluate.go b/vendor/github.com/hashicorp/terraform/terraform/evaluate.go index 38fe8767346d..ab65d475b1e7 100644 --- a/vendor/github.com/hashicorp/terraform/terraform/evaluate.go +++ b/vendor/github.com/hashicorp/terraform/terraform/evaluate.go @@ -215,6 +215,23 @@ func (d *evaluationStateData) GetInputVariable(addr addrs.InputVariable, rng tfd d.Evaluator.VariableValuesLock.Lock() defer d.Evaluator.VariableValuesLock.Unlock() + // During the validate walk, input variables are always unknown so + // that we are validating the configuration for all possible input values + // rather than for a specific set. Checking against a specific set of + // input values then happens during the plan walk. + // + // This is important because otherwise the validation walk will tend to be + // overly strict, requiring expressions throughout the configuration to + // be complicated to accommodate all possible inputs, whereas returning + // known here allows for simpler patterns like using input values as + // guards to broadly enable/disable resources, avoid processing things + // that are disabled, etc. Terraform's static validation leans towards + // being liberal in what it accepts because the subsequent plan walk has + // more information available and so can be more conservative. + if d.Operation == walkValidate { + return cty.UnknownVal(wantType), diags + } + moduleAddrStr := d.ModulePath.String() vals := d.Evaluator.VariableValues[moduleAddrStr] if vals == nil { diff --git a/vendor/modules.txt b/vendor/modules.txt index cacfb1c3ee48..fe727b445d8a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -187,7 +187,7 @@ github.com/hashicorp/hcl/hcl/scanner github.com/hashicorp/hcl/hcl/strconv github.com/hashicorp/hcl/json/scanner github.com/hashicorp/hcl/json/token -# github.com/hashicorp/hcl2 v0.0.0-20190402200843-8b450a7d58f9 +# github.com/hashicorp/hcl2 v0.0.0-20190416162332-2c5a4b7d729a github.com/hashicorp/hcl2/hcl github.com/hashicorp/hcl2/hcl/hclsyntax github.com/hashicorp/hcl2/hcldec @@ -205,7 +205,7 @@ github.com/hashicorp/hil/parser github.com/hashicorp/hil/scanner # github.com/hashicorp/logutils v1.0.0 github.com/hashicorp/logutils -# github.com/hashicorp/terraform v0.12.0-alpha4.0.20190410234817-9e158400c228 +# github.com/hashicorp/terraform v0.12.0-alpha4.0.20190417210818-177a7afb781f github.com/hashicorp/terraform/plugin github.com/hashicorp/terraform/helper/hashcode github.com/hashicorp/terraform/helper/mutexkv