]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/helper/schema/shims.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / helper / schema / shims.go
1 package schema
2
3 import (
4 "encoding/json"
5
6 "github.com/zclconf/go-cty/cty"
7 ctyjson "github.com/zclconf/go-cty/cty/json"
8
9 "github.com/hashicorp/terraform/config"
10 "github.com/hashicorp/terraform/configs/configschema"
11 "github.com/hashicorp/terraform/terraform"
12 )
13
14 // DiffFromValues takes the current state and desired state as cty.Values and
15 // derives a terraform.InstanceDiff to give to the legacy providers. This is
16 // used to take the states provided by the new ApplyResourceChange method and
17 // convert them to a state+diff required for the legacy Apply method.
18 func DiffFromValues(prior, planned cty.Value, res *Resource) (*terraform.InstanceDiff, error) {
19 return diffFromValues(prior, planned, res, nil)
20 }
21
22 // diffFromValues takes an additional CustomizeDiffFunc, so we can generate our
23 // test fixtures from the legacy tests. In the new provider protocol the diff
24 // only needs to be created for the apply operation, and any customizations
25 // have already been done.
26 func diffFromValues(prior, planned cty.Value, res *Resource, cust CustomizeDiffFunc) (*terraform.InstanceDiff, error) {
27 instanceState, err := res.ShimInstanceStateFromValue(prior)
28 if err != nil {
29 return nil, err
30 }
31
32 configSchema := res.CoreConfigSchema()
33
34 cfg := terraform.NewResourceConfigShimmed(planned, configSchema)
35 removeConfigUnknowns(cfg.Config)
36 removeConfigUnknowns(cfg.Raw)
37
38 diff, err := schemaMap(res.Schema).Diff(instanceState, cfg, cust, nil, false)
39 if err != nil {
40 return nil, err
41 }
42
43 return diff, err
44 }
45
46 // During apply the only unknown values are those which are to be computed by
47 // the resource itself. These may have been marked as unknown config values, and
48 // need to be removed to prevent the UnknownVariableValue from appearing the diff.
49 func removeConfigUnknowns(cfg map[string]interface{}) {
50 for k, v := range cfg {
51 switch v := v.(type) {
52 case string:
53 if v == config.UnknownVariableValue {
54 delete(cfg, k)
55 }
56 case []interface{}:
57 for _, i := range v {
58 if m, ok := i.(map[string]interface{}); ok {
59 removeConfigUnknowns(m)
60 }
61 }
62 case map[string]interface{}:
63 removeConfigUnknowns(v)
64 }
65 }
66 }
67
68 // ApplyDiff takes a cty.Value state and applies a terraform.InstanceDiff to
69 // get a new cty.Value state. This is used to convert the diff returned from
70 // the legacy provider Diff method to the state required for the new
71 // PlanResourceChange method.
72 func ApplyDiff(base cty.Value, d *terraform.InstanceDiff, schema *configschema.Block) (cty.Value, error) {
73 return d.ApplyToValue(base, schema)
74 }
75
76 // StateValueToJSONMap converts a cty.Value to generic JSON map via the cty JSON
77 // encoding.
78 func StateValueToJSONMap(val cty.Value, ty cty.Type) (map[string]interface{}, error) {
79 js, err := ctyjson.Marshal(val, ty)
80 if err != nil {
81 return nil, err
82 }
83
84 var m map[string]interface{}
85 if err := json.Unmarshal(js, &m); err != nil {
86 return nil, err
87 }
88
89 return m, nil
90 }
91
92 // JSONMapToStateValue takes a generic json map[string]interface{} and converts it
93 // to the specific type, ensuring that the values conform to the schema.
94 func JSONMapToStateValue(m map[string]interface{}, block *configschema.Block) (cty.Value, error) {
95 var val cty.Value
96
97 js, err := json.Marshal(m)
98 if err != nil {
99 return val, err
100 }
101
102 val, err = ctyjson.Unmarshal(js, block.ImpliedType())
103 if err != nil {
104 return val, err
105 }
106
107 return block.CoerceValue(val)
108 }
109
110 // StateValueFromInstanceState converts a terraform.InstanceState to a
111 // cty.Value as described by the provided cty.Type, and maintains the resource
112 // ID as the "id" attribute.
113 func StateValueFromInstanceState(is *terraform.InstanceState, ty cty.Type) (cty.Value, error) {
114 return is.AttrsAsObjectValue(ty)
115 }