forked from sl1pm4t/k2tf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hcl_block.go
113 lines (90 loc) · 2.84 KB
/
hcl_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
package main
import (
"github.com/sl1pm4t/k2tf/pkg/tfkschema"
"strings"
"github.com/hashicorp/hcl2/hclwrite"
log "github.com/sirupsen/logrus"
"github.com/zclconf/go-cty/cty"
)
// hclBlock is a wrapper for hclwrite.Block that allows tagging some extra
// metadata to each block.
type hclBlock struct {
//
name string
//
fieldName string
// The parent hclBlock to this hclBlock
parent *hclBlock
// The wrapped HCL block
hcl *hclwrite.Block
// hasValue means a child field of this block had a non-nil / non-zero value.
// If this is false when closeBlock() is called, the block won't be appended to
// parent
hasValue bool
// inlined flags whether this block is "transparent" Some Structs in the
// Kubernetes API structure are marked as "inline", meaning they don't create
// a new block, and their child value is propagated up the hierarchy.
// See v1.Volume as an example
inlined bool
// inlined flags whether this block is supported in the Terraform Provider schema
// Unsupported blocks will be excluded from HCL rendering
unsupported bool
}
// A child block is adding a sub-block, write HCL to:
// - this hclBlock's hcl Body if this block is not inlined
// - parent's HCL body if this block is "inlined"
func (b *hclBlock) AppendBlock(hcl *hclwrite.Block) {
if b.inlined {
// append to parent
b.parent.AppendBlock(hcl)
} else {
b.hcl.Body().AppendBlock(hcl)
}
}
// A child block is adding an attribute, write HCL to:
// - this hclBlock's hcl Body if this block is not inlined
// - parent's HCL body if this block is "inlined"
func (b *hclBlock) SetAttributeValue(name string, val cty.Value) {
if includeUnsupported || tfkschema.IsAttributeSupported(b.FullSchemaName()+"."+name) {
if b.inlined {
// append to parent
b.parent.SetAttributeValue(name, val)
} else {
b.hcl.Body().SetAttributeValue(name, val)
}
} else {
log.Debugf("skipping attribute: %s - not supported by provider", name)
}
}
func (b *hclBlock) FullSchemaName() string {
parentName := ""
if b.parent != nil {
parentName = b.parent.FullSchemaName()
}
if b.inlined {
return parentName
}
return strings.TrimLeft(parentName+"."+b.name, ".")
}
func (b *hclBlock) isSupportedAttribute() bool {
return tfkschema.IsAttributeSupported(b.FullSchemaName())
}
func (b *hclBlock) isRequired() bool {
required := tfkschema.IsAttributeRequired(b.FullSchemaName())
if required && !b.hasValue && !b.parent.isRequired() {
// If current attribute has no value, only flag as required if parent(s) are also required.
// This is to match how Terraform handles the Required flag of nested attributes.
required = false
}
return required
}
func (b *hclBlock) FullFieldName() string {
parentName := ""
if b.parent != nil {
parentName = b.parent.FullFieldName()
}
if b.inlined {
return parentName
}
return strings.TrimLeft(parentName+"."+b.fieldName, ".")
}