-
Notifications
You must be signed in to change notification settings - Fork 98
/
Copy pathblock.go
218 lines (183 loc) · 7.04 KB
/
block.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
package tfsdk
import (
"fmt"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-go/tftypes"
)
var _ tftypes.AttributePathStepper = Block{}
// Block must satify the fwschema.Block interface. It must also satisfy
// fwxschema.BlockWithPlanModifiers and fwxschema.BlockWithValidators
// interfaces, however we cannot check that here or it would introduce an
// import cycle.
var _ fwschema.Block = Block{}
// Block defines the constraints and behaviors of a single structural field in a
// schema.
//
// The NestingMode field must be set or a runtime error will be raised by the
// framework when fetching the schema.
//
// Deprecated: Use datasource/schema.Block, provider/schema.Block, or
// resource/schema.Block instead. This can be switched by using the
// datasource/schema.Schema, provider/schema.Schema, or resource/schema.Schema
// types.
type Block struct {
// Attributes are value fields inside the block. This map of attributes
// behaves exactly like the map of attributes on the Schema type.
Attributes map[string]Attribute
// Blocks can have their own nested blocks. This nested map of blocks
// behaves exactly like the map of blocks on the Schema type.
Blocks map[string]Block
// DeprecationMessage defines warning diagnostic details to display to
// practitioners configuring this Block. The warning diagnostic summary
// is automatically set to "Block Deprecated" along with configuration
// source file and line information.
//
// This warning diagnostic is only displayed during Terraform's validation
// phase when this field is a non-empty string and if the practitioner
// configuration attempts to set the block value to a known or unknown
// value (which may eventually be null).
//
// Set this field to a practitioner actionable message such as:
//
// - "Configure other_attribute instead. This block will be removed
// in the next major version of the provider."
// - "Remove this block's configuration as it no longer is used and
// the block will be removed in the next major version of the
// provider."
//
DeprecationMessage string
// Description is used in various tooling, like the language server, to
// give practitioners more information about what this attribute is,
// what it's for, and how it should be used. It should be written as
// plain text, with no special formatting.
Description string
// MarkdownDescription is used in various tooling, like the
// documentation generator, to give practitioners more information
// about what this attribute is, what it's for, and how it should be
// used. It should be formatted using Markdown.
MarkdownDescription string
// MaxItems is the maximum number of blocks that can be present in a
// practitioner configuration.
MaxItems int64
// MinItems is the minimum number of blocks that must be present in a
// practitioner configuration. Setting to 1 or above effectively marks
// this configuration as required.
MinItems int64
// NestingMode indicates the block kind. This field must be set or a
// runtime error will be raised by the framework when fetching the schema.
NestingMode fwschema.BlockNestingMode
// PlanModifiers defines a sequence of modifiers for this block at
// plan time. Block-level plan modifications occur before any
// resource-level plan modifications.
//
// Any errors will prevent further execution of this sequence
// of modifiers and modifiers associated with any nested Attribute or
// Block, but will not prevent execution of PlanModifiers on any
// other Attribute or Block in the Schema.
//
// Plan modification only applies to resources, not data sources or
// providers. Setting PlanModifiers on a data source or provider attribute
// will have no effect.
PlanModifiers AttributePlanModifiers
// Validators defines validation functionality for the block.
Validators []AttributeValidator
}
// ApplyTerraform5AttributePathStep allows Blocks to be walked using
// tftypes.Walk and tftypes.Transform.
func (b Block) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) {
switch b.NestingMode {
case BlockNestingModeList:
_, ok := step.(tftypes.ElementKeyInt)
if !ok {
return nil, fmt.Errorf("can't apply %T to block NestingModeList", step)
}
return b.GetNestedObject(), nil
case BlockNestingModeSet:
_, ok := step.(tftypes.ElementKeyValue)
if !ok {
return nil, fmt.Errorf("can't apply %T to block NestingModeSet", step)
}
return b.GetNestedObject(), nil
case BlockNestingModeSingle:
_, ok := step.(tftypes.AttributeName)
if !ok {
return nil, fmt.Errorf("can't apply %T to block NestingModeSingle", step)
}
return b.GetNestedObject().ApplyTerraform5AttributePathStep(step)
default:
return nil, fmt.Errorf("unsupported block nesting mode: %v", b.NestingMode)
}
}
// Equal returns true if `b` and `o` should be considered Equal.
func (b Block) Equal(o fwschema.Block) bool {
return fwschema.BlocksEqual(b, o)
}
// GetDeprecationMessage satisfies the fwschema.Block interface.
func (b Block) GetDeprecationMessage() string {
return b.DeprecationMessage
}
// GetDescription satisfies the fwschema.Block interface.
func (b Block) GetDescription() string {
return b.Description
}
// GetMarkdownDescription satisfies the fwschema.Block interface.
func (b Block) GetMarkdownDescription() string {
return b.MarkdownDescription
}
// GetMaxItems satisfies the fwschema.Block interface.
func (b Block) GetMaxItems() int64 {
return b.MaxItems
}
// GetMinItems satisfies the fwschema.Block interface.
func (b Block) GetMinItems() int64 {
return b.MinItems
}
// GetNestedObject returns a generated NestedBlockObject from the
// Attributes and Blocks field values.
func (b Block) GetNestedObject() fwschema.NestedBlockObject {
return nestedBlockObject{
Attributes: b.Attributes,
Blocks: b.Blocks,
}
}
// GetNestingMode satisfies the fwschema.Block interface.
func (b Block) GetNestingMode() fwschema.BlockNestingMode {
return b.NestingMode
}
// GetPlanModifiers satisfies the fwxschema.BlockWithPlanModifiers
// interface.
func (b Block) GetPlanModifiers() AttributePlanModifiers {
return b.PlanModifiers
}
// GetValidators satisfies the fwxschema.BlockWithValidators interface.
func (b Block) GetValidators() []AttributeValidator {
return b.Validators
}
// attributeType returns an attr.Type corresponding to the block.
func (b Block) Type() attr.Type {
attrType := types.ObjectType{
AttrTypes: map[string]attr.Type{},
}
for attrName, attr := range b.Attributes {
attrType.AttrTypes[attrName] = attr.GetType()
}
for blockName, block := range b.Blocks {
attrType.AttrTypes[blockName] = block.Type()
}
switch b.NestingMode {
case BlockNestingModeList:
return types.ListType{
ElemType: attrType,
}
case BlockNestingModeSet:
return types.SetType{
ElemType: attrType,
}
case BlockNestingModeSingle:
return attrType
default:
panic(fmt.Sprintf("unsupported block nesting mode: %v", b.NestingMode))
}
}