mirror of
https://github.com/opentffoundation/opentf.git
synced 2026-03-11 04:00:50 -04:00
This is a light revamp of our plan output to make use of Terraform core's new ability to report both the previous run state and the refreshed state, allowing us to explicitly report changes made outside of Terraform. Because whether a plan has "changes" or not is no longer such a straightforward matter, this now merges views.Operation.Plan with views.Operation.PlanNoChanges to produce a single function that knows how to report all of the various permutations. This was also an opportunity to fill some holes in our previous logic which caused it to produce some confusing messages, including a new tailored message for when "terraform destroy" detects that nothing needs to be destroyed. This also allows users to request the refresh-only planning mode using a new -refresh-only command line option. In that case, Terraform _only_ performs drift detection, and so applying a refresh-only plan only involves writing a new state snapshot, without changing any real infrastructure objects.
129 lines
2.9 KiB
Go
129 lines
2.9 KiB
Go
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) DriftSummary(cs *json.ChangeSummary) {
|
|
v.log.Info(
|
|
cs.String(),
|
|
"type", json.MessageDriftSummary,
|
|
"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,
|
|
)
|
|
}
|