/
sanitize_plan.go
114 lines (99 loc) · 3.23 KB
/
sanitize_plan.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
package sanitize
import (
"errors"
tfjson "github.com/hashicorp/terraform-json"
)
const DefaultSensitiveValue = "REDACTED_SENSITIVE"
var NilPlanError = errors.New("nil plan supplied")
// SanitizePlan sanitizes the entirety of a Plan, replacing sensitive
// values with the default value in DefaultSensitiveValue.
//
// See SanitizePlanWithValue for full detail on the where replacement
// takes place.
func SanitizePlan(old *tfjson.Plan) (*tfjson.Plan, error) {
return SanitizePlanWithValue(old, DefaultSensitiveValue)
}
// SanitizePlanWithValue sanitizes the entirety of a Plan to the best
// of its ability, depending on the provided metadata on sensitive
// values. These are found in:
//
// * ResourceChanges: Sanitized based on BeforeSensitive and
// AfterSensitive fields.
//
// * Variables: Based on variable config data found in the root
// module of the Config.
//
// * PlannedValues: Sanitized based on the values found in
// AfterSensitive in ResourceChanges. Outputs are sanitized
// according to the appropriate sensitivity flags provided for the
// output.
//
// * PriorState: Sanitized based on the values found in
// BeforeSensitive in ResourceChanges. Outputs are sanitized according
// to the appropriate sensitivity flags provided for the output.
//
// * OutputChanges: Sanitized based on the values found in
// BeforeSensitive and AfterSensitive. This generally means that
// any sensitive output will have OutputChange fully obfuscated as
// the BeforeSensitive and AfterSensitive in outputs are opaquely the
// same.
//
// Sensitive values are replaced with the value supplied with
// replaceWith. A copy of the Plan is returned.
func SanitizePlanWithValue(old *tfjson.Plan, replaceWith interface{}) (*tfjson.Plan, error) {
if old == nil {
return nil, NilPlanError
}
result, err := copyPlan(old)
if err != nil {
return nil, err
}
// Sanitize ResourceChanges
for i := range result.ResourceChanges {
result.ResourceChanges[i].Change, err = SanitizeChange(result.ResourceChanges[i].Change, replaceWith)
if err != nil {
return nil, err
}
}
// Sanitize Variables
result.Variables, err = SanitizePlanVariables(result.Variables, result.Config.RootModule.Variables, replaceWith)
if err != nil {
return nil, err
}
// Sanitize PlannedValues
result.PlannedValues.RootModule, err = SanitizeStateModule(
result.PlannedValues.RootModule,
result.ResourceChanges,
SanitizeStateModuleChangeModeAfter,
replaceWith)
if err != nil {
return nil, err
}
result.PlannedValues.Outputs, err = SanitizeStateOutputs(result.PlannedValues.Outputs, replaceWith)
if err != nil {
return nil, err
}
// Sanitize PriorState
if result.PriorState != nil {
result.PriorState.Values.RootModule, err = SanitizeStateModule(
result.PriorState.Values.RootModule,
result.ResourceChanges,
SanitizeStateModuleChangeModeBefore,
replaceWith)
if err != nil {
return nil, err
}
result.PriorState.Values.Outputs, err = SanitizeStateOutputs(result.PriorState.Values.Outputs, replaceWith)
if err != nil {
return nil, err
}
}
// Sanitize OutputChanges
for k := range result.OutputChanges {
result.OutputChanges[k], err = SanitizeChange(result.OutputChanges[k], replaceWith)
if err != nil {
return nil, err
}
}
return result, nil
}