/
json_view.go
120 lines (106 loc) · 2.73 KB
/
json_view.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
package views
import (
encJson "encoding/json"
"fmt"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/terraform/command/views/json"
"github.com/hashicorp/terraform/tfdiags"
tfversion "github.com/hashicorp/terraform/version"
)
// This version describes the schema of JSON UI messages. This version must be
// updated after making any changes to this view, the jsonHook, or any of the
// command/views/json package.
const JSON_UI_VERSION = "0.1.0"
func NewJSONView(view *View) *JSONView {
log := hclog.New(&hclog.LoggerOptions{
Name: "terraform.ui",
Output: view.streams.Stdout.File,
JSONFormat: true,
})
jv := &JSONView{
log: log,
view: view,
}
jv.Version()
return jv
}
type JSONView struct {
// hclog is used for all output in JSON UI mode. The logger has an internal
// mutex to ensure that messages are not interleaved.
log hclog.Logger
// We hold a reference to the view entirely to allow us to access the
// ConfigSources function pointer, in order to render source snippets into
// diagnostics. This is even more unfortunate than the same reference in the
// view.
//
// Do not be tempted to dereference the configSource value upon logger init,
// as it will likely be updated later.
view *View
}
func (v *JSONView) Version() {
version := tfversion.String()
v.log.Info(
fmt.Sprintf("Terraform %s", version),
"type", json.MessageVersion,
"terraform", version,
"ui", JSON_UI_VERSION,
)
}
func (v *JSONView) Log(message string) {
v.log.Info(message, "type", json.MessageLog)
}
func (v *JSONView) StateDump(state string) {
v.log.Info(
"Emergency state dump",
"type", json.MessageLog,
"state", encJson.RawMessage(state),
)
}
func (v *JSONView) Diagnostics(diags tfdiags.Diagnostics) {
sources := v.view.configSources()
for _, diag := range diags {
diagnostic := json.NewDiagnostic(diag, sources)
switch diag.Severity() {
case tfdiags.Warning:
v.log.Warn(
fmt.Sprintf("Warning: %s", diag.Description().Summary),
"type", json.MessageDiagnostic,
"diagnostic", diagnostic,
)
default:
v.log.Error(
fmt.Sprintf("Error: %s", diag.Description().Summary),
"type", json.MessageDiagnostic,
"diagnostic", diagnostic,
)
}
}
}
func (v *JSONView) PlannedChange(c *json.ResourceInstanceChange) {
v.log.Info(
c.String(),
"type", json.MessagePlannedChange,
"change", c,
)
}
func (v *JSONView) ChangeSummary(cs *json.ChangeSummary) {
v.log.Info(
cs.String(),
"type", json.MessageChangeSummary,
"changes", cs,
)
}
func (v *JSONView) Hook(h json.Hook) {
v.log.Info(
h.String(),
"type", h.HookType(),
"hook", h,
)
}
func (v *JSONView) Outputs(outputs json.Outputs) {
v.log.Info(
outputs.String(),
"type", json.MessageOutputs,
"outputs", outputs,
)
}