]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/plugin/convert/schema.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / plugin / convert / schema.go
1 package convert
2
3 import (
4 "encoding/json"
5 "reflect"
6 "sort"
7
8 "github.com/hashicorp/terraform/configs/configschema"
9 proto "github.com/hashicorp/terraform/internal/tfplugin5"
10 "github.com/hashicorp/terraform/providers"
11 )
12
13 // ConfigSchemaToProto takes a *configschema.Block and converts it to a
14 // proto.Schema_Block for a grpc response.
15 func ConfigSchemaToProto(b *configschema.Block) *proto.Schema_Block {
16 block := &proto.Schema_Block{}
17
18 for _, name := range sortedKeys(b.Attributes) {
19 a := b.Attributes[name]
20 attr := &proto.Schema_Attribute{
21 Name: name,
22 Description: a.Description,
23 Optional: a.Optional,
24 Computed: a.Computed,
25 Required: a.Required,
26 Sensitive: a.Sensitive,
27 }
28
29 ty, err := json.Marshal(a.Type)
30 if err != nil {
31 panic(err)
32 }
33
34 attr.Type = ty
35
36 block.Attributes = append(block.Attributes, attr)
37 }
38
39 for _, name := range sortedKeys(b.BlockTypes) {
40 b := b.BlockTypes[name]
41 block.BlockTypes = append(block.BlockTypes, protoSchemaNestedBlock(name, b))
42 }
43
44 return block
45 }
46
47 func protoSchemaNestedBlock(name string, b *configschema.NestedBlock) *proto.Schema_NestedBlock {
48 var nesting proto.Schema_NestedBlock_NestingMode
49 switch b.Nesting {
50 case configschema.NestingSingle:
51 nesting = proto.Schema_NestedBlock_SINGLE
52 case configschema.NestingGroup:
53 nesting = proto.Schema_NestedBlock_GROUP
54 case configschema.NestingList:
55 nesting = proto.Schema_NestedBlock_LIST
56 case configschema.NestingSet:
57 nesting = proto.Schema_NestedBlock_SET
58 case configschema.NestingMap:
59 nesting = proto.Schema_NestedBlock_MAP
60 default:
61 nesting = proto.Schema_NestedBlock_INVALID
62 }
63 return &proto.Schema_NestedBlock{
64 TypeName: name,
65 Block: ConfigSchemaToProto(&b.Block),
66 Nesting: nesting,
67 MinItems: int64(b.MinItems),
68 MaxItems: int64(b.MaxItems),
69 }
70 }
71
72 // ProtoToProviderSchema takes a proto.Schema and converts it to a providers.Schema.
73 func ProtoToProviderSchema(s *proto.Schema) providers.Schema {
74 return providers.Schema{
75 Version: s.Version,
76 Block: ProtoToConfigSchema(s.Block),
77 }
78 }
79
80 // ProtoToConfigSchema takes the GetSchcema_Block from a grpc response and converts it
81 // to a terraform *configschema.Block.
82 func ProtoToConfigSchema(b *proto.Schema_Block) *configschema.Block {
83 block := &configschema.Block{
84 Attributes: make(map[string]*configschema.Attribute),
85 BlockTypes: make(map[string]*configschema.NestedBlock),
86 }
87
88 for _, a := range b.Attributes {
89 attr := &configschema.Attribute{
90 Description: a.Description,
91 Required: a.Required,
92 Optional: a.Optional,
93 Computed: a.Computed,
94 Sensitive: a.Sensitive,
95 }
96
97 if err := json.Unmarshal(a.Type, &attr.Type); err != nil {
98 panic(err)
99 }
100
101 block.Attributes[a.Name] = attr
102 }
103
104 for _, b := range b.BlockTypes {
105 block.BlockTypes[b.TypeName] = schemaNestedBlock(b)
106 }
107
108 return block
109 }
110
111 func schemaNestedBlock(b *proto.Schema_NestedBlock) *configschema.NestedBlock {
112 var nesting configschema.NestingMode
113 switch b.Nesting {
114 case proto.Schema_NestedBlock_SINGLE:
115 nesting = configschema.NestingSingle
116 case proto.Schema_NestedBlock_GROUP:
117 nesting = configschema.NestingGroup
118 case proto.Schema_NestedBlock_LIST:
119 nesting = configschema.NestingList
120 case proto.Schema_NestedBlock_MAP:
121 nesting = configschema.NestingMap
122 case proto.Schema_NestedBlock_SET:
123 nesting = configschema.NestingSet
124 default:
125 // In all other cases we'll leave it as the zero value (invalid) and
126 // let the caller validate it and deal with this.
127 }
128
129 nb := &configschema.NestedBlock{
130 Nesting: nesting,
131 MinItems: int(b.MinItems),
132 MaxItems: int(b.MaxItems),
133 }
134
135 nested := ProtoToConfigSchema(b.Block)
136 nb.Block = *nested
137 return nb
138 }
139
140 // sortedKeys returns the lexically sorted keys from the given map. This is
141 // used to make schema conversions are deterministic. This panics if map keys
142 // are not a string.
143 func sortedKeys(m interface{}) []string {
144 v := reflect.ValueOf(m)
145 keys := make([]string, v.Len())
146
147 mapKeys := v.MapKeys()
148 for i, k := range mapKeys {
149 keys[i] = k.Interface().(string)
150 }
151
152 sort.Strings(keys)
153 return keys
154 }