diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper/schema/shims.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/helper/schema/shims.go | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/shims.go b/vendor/github.com/hashicorp/terraform/helper/schema/shims.go new file mode 100644 index 0000000..203d017 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/helper/schema/shims.go | |||
@@ -0,0 +1,115 @@ | |||
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 | } | ||