]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blobdiff - vendor/github.com/hashicorp/terraform/helper/schema/backend.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / helper / schema / backend.go
index 57fbba7447bbcf05624eec00c509de9678e381d4..c8d8ae28c673dabdcebe97050a07186dcf00a046 100644 (file)
@@ -2,8 +2,15 @@ package schema
 
 import (
        "context"
+       "fmt"
 
+       "github.com/hashicorp/terraform/tfdiags"
+       "github.com/zclconf/go-cty/cty"
+
+       "github.com/hashicorp/terraform/config/hcl2shim"
+       "github.com/hashicorp/terraform/configs/configschema"
        "github.com/hashicorp/terraform/terraform"
+       ctyconvert "github.com/zclconf/go-cty/cty/convert"
 )
 
 // Backend represents a partial backend.Backend implementation and simplifies
@@ -38,41 +45,123 @@ func FromContextBackendConfig(ctx context.Context) *ResourceData {
        return ctx.Value(backendConfigKey).(*ResourceData)
 }
 
-func (b *Backend) Input(
-       input terraform.UIInput,
-       c *terraform.ResourceConfig) (*terraform.ResourceConfig, error) {
+func (b *Backend) ConfigSchema() *configschema.Block {
+       // This is an alias of CoreConfigSchema just to implement the
+       // backend.Backend interface.
+       return b.CoreConfigSchema()
+}
+
+func (b *Backend) PrepareConfig(configVal cty.Value) (cty.Value, tfdiags.Diagnostics) {
        if b == nil {
-               return c, nil
+               return configVal, nil
        }
+       var diags tfdiags.Diagnostics
+       var err error
 
-       return schemaMap(b.Schema).Input(input, c)
-}
+       // In order to use Transform below, this needs to be filled out completely
+       // according the schema.
+       configVal, err = b.CoreConfigSchema().CoerceValue(configVal)
+       if err != nil {
+               return configVal, diags.Append(err)
+       }
 
-func (b *Backend) Validate(c *terraform.ResourceConfig) ([]string, []error) {
-       if b == nil {
-               return nil, nil
+       // lookup any required, top-level attributes that are Null, and see if we
+       // have a Default value available.
+       configVal, err = cty.Transform(configVal, func(path cty.Path, val cty.Value) (cty.Value, error) {
+               // we're only looking for top-level attributes
+               if len(path) != 1 {
+                       return val, nil
+               }
+
+               // nothing to do if we already have a value
+               if !val.IsNull() {
+                       return val, nil
+               }
+
+               // get the Schema definition for this attribute
+               getAttr, ok := path[0].(cty.GetAttrStep)
+               // these should all exist, but just ignore anything strange
+               if !ok {
+                       return val, nil
+               }
+
+               attrSchema := b.Schema[getAttr.Name]
+               // continue to ignore anything that doesn't match
+               if attrSchema == nil {
+                       return val, nil
+               }
+
+               // this is deprecated, so don't set it
+               if attrSchema.Deprecated != "" || attrSchema.Removed != "" {
+                       return val, nil
+               }
+
+               // find a default value if it exists
+               def, err := attrSchema.DefaultValue()
+               if err != nil {
+                       diags = diags.Append(fmt.Errorf("error getting default for %q: %s", getAttr.Name, err))
+                       return val, err
+               }
+
+               // no default
+               if def == nil {
+                       return val, nil
+               }
+
+               // create a cty.Value and make sure it's the correct type
+               tmpVal := hcl2shim.HCL2ValueFromConfigValue(def)
+
+               // helper/schema used to allow setting "" to a bool
+               if val.Type() == cty.Bool && tmpVal.RawEquals(cty.StringVal("")) {
+                       // return a warning about the conversion
+                       diags = diags.Append("provider set empty string as default value for bool " + getAttr.Name)
+                       tmpVal = cty.False
+               }
+
+               val, err = ctyconvert.Convert(tmpVal, val.Type())
+               if err != nil {
+                       diags = diags.Append(fmt.Errorf("error setting default for %q: %s", getAttr.Name, err))
+               }
+
+               return val, err
+       })
+       if err != nil {
+               // any error here was already added to the diagnostics
+               return configVal, diags
        }
 
-       return schemaMap(b.Schema).Validate(c)
+       shimRC := b.shimConfig(configVal)
+       warns, errs := schemaMap(b.Schema).Validate(shimRC)
+       for _, warn := range warns {
+               diags = diags.Append(tfdiags.SimpleWarning(warn))
+       }
+       for _, err := range errs {
+               diags = diags.Append(err)
+       }
+       return configVal, diags
 }
 
-func (b *Backend) Configure(c *terraform.ResourceConfig) error {
+func (b *Backend) Configure(obj cty.Value) tfdiags.Diagnostics {
        if b == nil {
                return nil
        }
 
+       var diags tfdiags.Diagnostics
        sm := schemaMap(b.Schema)
+       shimRC := b.shimConfig(obj)
 
        // Get a ResourceData for this configuration. To do this, we actually
        // generate an intermediary "diff" although that is never exposed.
-       diff, err := sm.Diff(nil, c, nil, nil)
+       diff, err := sm.Diff(nil, shimRC, nil, nil, true)
        if err != nil {
-               return err
+               diags = diags.Append(err)
+               return diags
        }
 
        data, err := sm.Data(nil, diff)
        if err != nil {
-               return err
+               diags = diags.Append(err)
+               return diags
        }
        b.config = data
 
@@ -80,11 +169,28 @@ func (b *Backend) Configure(c *terraform.ResourceConfig) error {
                err = b.ConfigureFunc(context.WithValue(
                        context.Background(), backendConfigKey, data))
                if err != nil {
-                       return err
+                       diags = diags.Append(err)
+                       return diags
                }
        }
 
-       return nil
+       return diags
+}
+
+// shimConfig turns a new-style cty.Value configuration (which must be of
+// an object type) into a minimal old-style *terraform.ResourceConfig object
+// that should be populated enough to appease the not-yet-updated functionality
+// in this package. This should be removed once everything is updated.
+func (b *Backend) shimConfig(obj cty.Value) *terraform.ResourceConfig {
+       shimMap, ok := hcl2shim.ConfigValueFromHCL2(obj).(map[string]interface{})
+       if !ok {
+               // If the configVal was nil, we still want a non-nil map here.
+               shimMap = map[string]interface{}{}
+       }
+       return &terraform.ResourceConfig{
+               Config: shimMap,
+               Raw:    shimMap,
+       }
 }
 
 // Config returns the configuration. This is available after Configure is