-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmap_attribute.go
135 lines (116 loc) · 3.54 KB
/
map_attribute.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
package tfplanparse
import (
"fmt"
"strings"
)
type MapAttributeChange struct {
Name string
AttributeChanges []attributeChange
UpdateType UpdateType
}
var _ attributeChange = &MapAttributeChange{}
// IsMapAttributeChangeLine returns true if the line is a valid attribute change
// This requires the line to start with "+", "-" or "~", not be followed with "resource" or "data", and ends with "{".
func IsMapAttributeChangeLine(line string) bool {
line = strings.TrimSpace(line)
// validPrefix := strings.HasPrefix(line, "+") || strings.HasPrefix(line, "-") || strings.HasPrefix(line, "~")
validSuffix := strings.HasSuffix(line, "{") || IsOneLineEmptyMapAttribute(line)
return validSuffix && !IsResourceChangeLine(line)
}
// IsMapAttributeTerminator returns true if the line is a "}" or "},"
func IsMapAttributeTerminator(line string) bool {
return strings.TrimSuffix(strings.TrimSuffix(strings.TrimSpace(line), ","), " -> null") == "}"
}
// IsOneLineEmptyMapAttribute returns true if the line ends with a "{}"
func IsOneLineEmptyMapAttribute(line string) bool {
return strings.HasSuffix(line, "{}")
}
// NewMapAttributeChangeFromLine initializes an AttributeChange from a line containing an attribute change
// It expects a line that passes the IsAttributeChangeLine check
func NewMapAttributeChangeFromLine(line string) (*MapAttributeChange, error) {
line = strings.TrimSpace(line)
if !IsMapAttributeChangeLine(line) {
return nil, fmt.Errorf("%s is not a valid line to initialize a MapAttributeChange", line)
}
attributeName := getMultiLineAttributeName(line)
if strings.HasPrefix(line, "+") {
// add
return &MapAttributeChange{
Name: attributeName,
UpdateType: NewResource,
}, nil
} else if strings.HasPrefix(line, "-") {
// destroy
return &MapAttributeChange{
Name: attributeName,
UpdateType: DestroyResource,
}, nil
} else if strings.HasPrefix(line, "~") {
// replace
return &MapAttributeChange{
Name: attributeName,
UpdateType: UpdateInPlaceResource,
}, nil
} else {
return &MapAttributeChange{
Name: attributeName,
UpdateType: NoOpResource,
}, nil
}
}
// GetName returns the name of the attribute
func (m *MapAttributeChange) GetName() string {
return m.Name
}
// GetUpdateType returns the UpdateType of the attribute
func (m *MapAttributeChange) GetUpdateType() UpdateType {
return m.UpdateType
}
// IsSensitive returns true if the attribute contains a sensitive value
func (m *MapAttributeChange) IsSensitive() bool {
for _, ac := range m.AttributeChanges {
if ac.IsSensitive() {
return true
}
}
return false
}
// IsComputed returns true if the attribute contains a computed value
func (m *MapAttributeChange) IsComputed() bool {
for _, ac := range m.AttributeChanges {
if ac.IsComputed() {
return true
}
}
return false
}
// IsNoOp returns true if the attribute has not changed
func (m *MapAttributeChange) IsNoOp() bool {
return m.UpdateType == NoOpResource
}
func (m *MapAttributeChange) GetBefore(opts ...GetBeforeAfterOptions) interface{} {
result := map[string]interface{}{}
attrs:
for _, a := range m.AttributeChanges {
for _, opt := range opts {
if opt(a) {
continue attrs
}
}
result[a.GetName()] = a.GetBefore(opts...)
}
return result
}
func (m *MapAttributeChange) GetAfter(opts ...GetBeforeAfterOptions) interface{} {
result := map[string]interface{}{}
attrs:
for _, a := range m.AttributeChanges {
for _, opt := range opts {
if opt(a) {
continue attrs
}
}
result[a.GetName()] = a.GetAfter(opts...)
}
return result
}