-
Notifications
You must be signed in to change notification settings - Fork 9.4k
/
sensitive.go
92 lines (78 loc) · 3.42 KB
/
sensitive.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
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package structured
import (
"github.com/hashicorp/terraform/internal/command/jsonformat/computed"
"github.com/hashicorp/terraform/internal/plans"
)
type ProcessSensitiveInner func(change Change) computed.Diff
type CreateSensitiveDiff func(inner computed.Diff, beforeSensitive, afterSensitive bool, action plans.Action) computed.Diff
func (change Change) IsBeforeSensitive() bool {
if sensitive, ok := change.BeforeSensitive.(bool); ok {
return sensitive
}
return false
}
func (change Change) IsAfterSensitive() bool {
if sensitive, ok := change.AfterSensitive.(bool); ok {
return sensitive
}
return false
}
// CheckForSensitive is a helper function that handles all common functionality
// for processing a sensitive value.
//
// It returns the computed sensitive diff and true if this value was sensitive
// and needs to be rendered as such, otherwise it returns the second return
// value as false and the first value can be discarded.
//
// The actual processing of sensitive values happens within the
// ProcessSensitiveInner and CreateSensitiveDiff functions. Callers should
// implement these functions as appropriate when using this function.
//
// The ProcessSensitiveInner function should simply return a computed.Diff for
// the provided Change. The provided Change will be the same as the original
// change but with the sensitive metadata removed. The new inner diff is then
// passed into the actual CreateSensitiveDiff function which should return the
// actual sensitive diff.
//
// We include the inner change into the sensitive diff as a way to let the
// sensitive renderer have as much information as possible, while still letting
// it do the actual rendering.
func (change Change) CheckForSensitive(processInner ProcessSensitiveInner, createDiff CreateSensitiveDiff) (computed.Diff, bool) {
beforeSensitive := change.IsBeforeSensitive()
afterSensitive := change.IsAfterSensitive()
if !beforeSensitive && !afterSensitive {
return computed.Diff{}, false
}
// We are still going to give the change the contents of the actual change.
// So we create a new Change with everything matching the current value,
// except for the sensitivity.
//
// The change can choose what to do with this information, in most cases
// it will just be ignored in favour of printing `(sensitive value)`.
value := Change{
BeforeExplicit: change.BeforeExplicit,
AfterExplicit: change.AfterExplicit,
Before: change.Before,
After: change.After,
Unknown: change.Unknown,
BeforeSensitive: false,
AfterSensitive: false,
ReplacePaths: change.ReplacePaths,
RelevantAttributes: change.RelevantAttributes,
}
inner := processInner(value)
action := inner.Action
sensitiveStatusChanged := beforeSensitive != afterSensitive
// nullNoOp is a stronger NoOp, where not only is there no change happening
// but the before and after values are not explicitly set and are both
// null. This will override even the sensitive state changing.
nullNoOp := change.Before == nil && !change.BeforeExplicit && change.After == nil && !change.AfterExplicit
if action == plans.NoOp && sensitiveStatusChanged && !nullNoOp {
// Let's override this, since it means the sensitive status has changed
// rather than the actual content of the value.
action = plans.Update
}
return createDiff(inner, beforeSensitive, afterSensitive, action), true
}