mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
Merge pull request #32696 from hashicorp/sebasslash/sro-provisioner-logs
Handle provisioner log types when rendering structured logs
This commit is contained in:
commit
3f23a9e70a
@ -1262,6 +1262,103 @@ func TestCloud_applyDestroyNoConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloud_applyJSONWithProvisioner(t *testing.T) {
|
||||
b, bCleanup := testBackendWithName(t)
|
||||
defer bCleanup()
|
||||
|
||||
stream, close := terminal.StreamsForTesting(t)
|
||||
|
||||
b.renderer = &jsonformat.Renderer{
|
||||
Streams: stream,
|
||||
Colorize: mockColorize(),
|
||||
}
|
||||
input := testInput(t, map[string]string{
|
||||
"approve": "yes",
|
||||
})
|
||||
|
||||
op, configCleanup, done := testOperationApply(t, "./testdata/apply-json-with-provisioner")
|
||||
defer configCleanup()
|
||||
defer done(t)
|
||||
|
||||
op.UIIn = input
|
||||
op.UIOut = b.CLI
|
||||
op.Workspace = testBackendSingleWorkspaceName
|
||||
|
||||
mockSROWorkspace(t, b, op.Workspace)
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
if run.Result != backend.OperationSuccess {
|
||||
t.Fatalf("operation failed: %s", b.CLI.(*cli.MockUi).ErrorWriter.String())
|
||||
}
|
||||
|
||||
if run.PlanEmpty {
|
||||
t.Fatalf("expected a non-empty plan")
|
||||
}
|
||||
|
||||
if len(input.answers) > 0 {
|
||||
t.Fatalf("expected no unused answers, got: %v", input.answers)
|
||||
}
|
||||
|
||||
outp := close(t)
|
||||
gotOut := outp.Stdout()
|
||||
if !strings.Contains(gotOut, "null_resource.foo: Provisioning with 'local-exec'") {
|
||||
t.Fatalf("expected provisioner local-exec start in logs: %s", gotOut)
|
||||
}
|
||||
|
||||
if !strings.Contains(gotOut, "null_resource.foo: (local-exec):") {
|
||||
t.Fatalf("expected provisioner local-exec progress in logs: %s", gotOut)
|
||||
}
|
||||
|
||||
if !strings.Contains(gotOut, "Hello World!") {
|
||||
t.Fatalf("expected provisioner local-exec output in logs: %s", gotOut)
|
||||
}
|
||||
|
||||
stateMgr, _ := b.StateMgr(testBackendSingleWorkspaceName)
|
||||
// An error suggests that the state was not unlocked after apply
|
||||
if _, err := stateMgr.Lock(statemgr.NewLockInfo()); err != nil {
|
||||
t.Fatalf("unexpected error locking state after apply: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloud_applyJSONWithProvisionerError(t *testing.T) {
|
||||
b, bCleanup := testBackendWithName(t)
|
||||
defer bCleanup()
|
||||
|
||||
stream, close := terminal.StreamsForTesting(t)
|
||||
|
||||
b.renderer = &jsonformat.Renderer{
|
||||
Streams: stream,
|
||||
Colorize: mockColorize(),
|
||||
}
|
||||
|
||||
op, configCleanup, done := testOperationApply(t, "./testdata/apply-json-with-provisioner-error")
|
||||
defer configCleanup()
|
||||
defer done(t)
|
||||
|
||||
op.Workspace = testBackendSingleWorkspaceName
|
||||
|
||||
mockSROWorkspace(t, b, op.Workspace)
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
|
||||
outp := close(t)
|
||||
gotOut := outp.Stdout()
|
||||
|
||||
if !strings.Contains(gotOut, "local-exec provisioner error") {
|
||||
t.Fatalf("unexpected error in apply logs: %s", gotOut)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloud_applyPolicyPass(t *testing.T) {
|
||||
b, bCleanup := testBackendWithName(t)
|
||||
defer bCleanup()
|
||||
|
9
internal/cloud/testdata/apply-json-with-provisioner-error/apply.log
vendored
Normal file
9
internal/cloud/testdata/apply-json-with-provisioner-error/apply.log
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
{"@level":"info","@message":"Terraform 1.3.7","@module":"terraform.ui","@timestamp":"2023-01-20T15:50:04.623068-05:00","terraform":"1.3.7","type":"version","ui":"1.0"}
|
||||
{"@level":"info","@message":"null_resource.foo: Destroying... [id=5383176453498935794]","@module":"terraform.ui","@timestamp":"2023-02-16T10:13:14.725584-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"action":"delete","id_key":"id","id_value":"5383176453498935794"},"type":"apply_start"}
|
||||
{"@level":"info","@message":"null_resource.foo: Destruction complete after 0s","@module":"terraform.ui","@timestamp":"2023-02-16T10:13:14.728526-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"action":"delete","elapsed_seconds":0},"type":"apply_complete"}
|
||||
{"@level":"info","@message":"null_resource.foo: Creating...","@module":"terraform.ui","@timestamp":"2023-02-16T10:13:14.745016-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"action":"create"},"type":"apply_start"}
|
||||
{"@level":"info","@message":"null_resource.foo: Provisioning with 'local-exec'...","@module":"terraform.ui","@timestamp":"2023-02-16T10:13:14.748796-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"provisioner":"local-exec"},"type":"provision_start"}
|
||||
{"@level":"info","@message":"null_resource.foo: (local-exec): Executing: [\"/bin/sh\" \"-c\" \"exit 125\"]","@module":"terraform.ui","@timestamp":"2023-02-16T10:13:14.749082-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"provisioner":"local-exec","output":"Executing: [\"/bin/sh\" \"-c\" \"exit 125\"]"},"type":"provision_progress"}
|
||||
{"@level":"info","@message":"null_resource.foo: (local-exec) Provisioning errored","@module":"terraform.ui","@timestamp":"2023-02-16T10:13:14.751770-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"provisioner":"local-exec"},"type":"provision_errored"}
|
||||
{"@level":"info","@message":"null_resource.foo: Creation errored after 0s","@module":"terraform.ui","@timestamp":"2023-02-16T10:13:14.752082-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"action":"create","elapsed_seconds":0},"type":"apply_errored"}
|
||||
{"@level":"error","@message":"Error: local-exec provisioner error","@module":"terraform.ui","@timestamp":"2023-02-16T10:13:14.761681-05:00","diagnostic":{"severity":"error","summary":"local-exec provisioner error","detail":"Error running command 'exit 125': exit status 125. Output: ","address":"null_resource.foo","range":{"filename":"main.tf","start":{"line":2,"column":28,"byte":60},"end":{"line":2,"column":29,"byte":61}},"snippet":{"context":"resource \"null_resource\" \"foo\"","code":" provisioner \"local-exec\" {","start_line":2,"highlight_start_offset":27,"highlight_end_offset":28,"values":[]}},"type":"diagnostic"}
|
5
internal/cloud/testdata/apply-json-with-provisioner-error/main.tf
vendored
Normal file
5
internal/cloud/testdata/apply-json-with-provisioner-error/main.tf
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
resource "null_resource" "foo" {
|
||||
provisioner "local-exec" {
|
||||
command = "exit 125"
|
||||
}
|
||||
}
|
116
internal/cloud/testdata/apply-json-with-provisioner-error/plan-redacted.json
vendored
Normal file
116
internal/cloud/testdata/apply-json-with-provisioner-error/plan-redacted.json
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
{
|
||||
"plan_format_version": "1.1",
|
||||
"resource_drift": [],
|
||||
"resource_changes": [
|
||||
{
|
||||
"address": "null_resource.foo",
|
||||
"mode": "managed",
|
||||
"type": "null_resource",
|
||||
"name": "foo",
|
||||
"provider_name": "registry.terraform.io/hashicorp/null",
|
||||
"change": {
|
||||
"actions": [
|
||||
"create"
|
||||
],
|
||||
"before": null,
|
||||
"after": {
|
||||
"triggers": null
|
||||
},
|
||||
"after_unknown": {
|
||||
"id": true
|
||||
},
|
||||
"before_sensitive": false,
|
||||
"after_sensitive": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"relevant_attributes": [],
|
||||
"output_changes": {},
|
||||
"provider_schemas": {
|
||||
"registry.terraform.io/hashicorp/null": {
|
||||
"provider": {
|
||||
"version": 0,
|
||||
"block": {
|
||||
"description_kind": "plain"
|
||||
}
|
||||
},
|
||||
"resource_schemas": {
|
||||
"null_resource": {
|
||||
"version": 0,
|
||||
"block": {
|
||||
"attributes": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "This is set to a random value at create time.",
|
||||
"description_kind": "plain",
|
||||
"computed": true
|
||||
},
|
||||
"triggers": {
|
||||
"type": [
|
||||
"map",
|
||||
"string"
|
||||
],
|
||||
"description": "A map of arbitrary strings that, when changed, will force the null resource to be replaced, re-running any associated provisioners.",
|
||||
"description_kind": "plain",
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"description": "The `null_resource` resource implements the standard resource lifecycle but takes no further action.\n\nThe `triggers` argument allows specifying an arbitrary set of values that, when changed, will cause the resource to be replaced.",
|
||||
"description_kind": "plain"
|
||||
}
|
||||
}
|
||||
},
|
||||
"data_source_schemas": {
|
||||
"null_data_source": {
|
||||
"version": 0,
|
||||
"block": {
|
||||
"attributes": {
|
||||
"has_computed_default": {
|
||||
"type": "string",
|
||||
"description": "If set, its literal value will be stored and returned. If not, its value defaults to `\"default\"`. This argument exists primarily for testing and has little practical use.",
|
||||
"description_kind": "plain",
|
||||
"optional": true,
|
||||
"computed": true
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "This attribute is only present for some legacy compatibility issues and should not be used. It will be removed in a future version.",
|
||||
"description_kind": "plain",
|
||||
"deprecated": true,
|
||||
"computed": true
|
||||
},
|
||||
"inputs": {
|
||||
"type": [
|
||||
"map",
|
||||
"string"
|
||||
],
|
||||
"description": "A map of arbitrary strings that is copied into the `outputs` attribute, and accessible directly for interpolation.",
|
||||
"description_kind": "plain",
|
||||
"optional": true
|
||||
},
|
||||
"outputs": {
|
||||
"type": [
|
||||
"map",
|
||||
"string"
|
||||
],
|
||||
"description": "After the data source is \"read\", a copy of the `inputs` map.",
|
||||
"description_kind": "plain",
|
||||
"computed": true
|
||||
},
|
||||
"random": {
|
||||
"type": "string",
|
||||
"description": "A random value. This is primarily for testing and has little practical use; prefer the [hashicorp/random provider](https://registry.terraform.io/providers/hashicorp/random) for more practical random number use-cases.",
|
||||
"description_kind": "plain",
|
||||
"computed": true
|
||||
}
|
||||
},
|
||||
"description": "The `null_data_source` data source implements the standard data source lifecycle but does not\ninteract with any external APIs.\n\nHistorically, the `null_data_source` was typically used to construct intermediate values to re-use elsewhere in configuration. The\nsame can now be achieved using [locals](https://www.terraform.io/docs/language/values/locals.html).\n",
|
||||
"description_kind": "plain",
|
||||
"deprecated": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"provider_format_version": "1.0"
|
||||
}
|
3
internal/cloud/testdata/apply-json-with-provisioner-error/plan.log
vendored
Normal file
3
internal/cloud/testdata/apply-json-with-provisioner-error/plan.log
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{"@level":"info","@message":"Terraform 1.3.7","@module":"terraform.ui","@timestamp":"2023-01-20T15:50:04.623068-05:00","terraform":"1.3.7","type":"version","ui":"1.0"}
|
||||
{"@level":"info","@message":"null_resource.foo: Plan to create","@module":"terraform.ui","@timestamp":"2023-01-20T15:50:04.822722-05:00","change":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"action":"create"},"type":"planned_change"}
|
||||
{"@level":"info","@message":"Plan: 1 to add, 0 to change, 0 to destroy.","@module":"terraform.ui","@timestamp":"2023-01-20T15:50:04.822787-05:00","changes":{"add":1,"change":0,"remove":0,"operation":"plan"},"type":"change_summary"}
|
10
internal/cloud/testdata/apply-json-with-provisioner/apply.log
vendored
Normal file
10
internal/cloud/testdata/apply-json-with-provisioner/apply.log
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
{"@level":"info","@message":"null_resource.foo: Destroying... [id=102500065134967380]","@module":"terraform.ui","@timestamp":"2023-02-16T10:15:39.614616-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"action":"delete","id_key":"id","id_value":"102500065134967380"},"type":"apply_start"}
|
||||
{"@level":"info","@message":"null_resource.foo: Destruction complete after 0s","@module":"terraform.ui","@timestamp":"2023-02-16T10:15:39.615777-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"action":"delete","elapsed_seconds":0},"type":"apply_complete"}
|
||||
{"@level":"info","@message":"null_resource.foo: Creating...","@module":"terraform.ui","@timestamp":"2023-02-16T10:15:39.621975-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"action":"create"},"type":"apply_start"}
|
||||
{"@level":"info","@message":"null_resource.foo: Provisioning with 'local-exec'...","@module":"terraform.ui","@timestamp":"2023-02-16T10:15:39.622630-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"provisioner":"local-exec"},"type":"provision_start"}
|
||||
{"@level":"info","@message":"null_resource.foo: (local-exec): Executing: [\"/bin/sh\" \"-c\" \"echo Hello World!\"]","@module":"terraform.ui","@timestamp":"2023-02-16T10:15:39.622702-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"provisioner":"local-exec","output":"Executing: [\"/bin/sh\" \"-c\" \"echo Hello World!\"]"},"type":"provision_progress"}
|
||||
{"@level":"info","@message":"null_resource.foo: (local-exec): Hello World!","@module":"terraform.ui","@timestamp":"2023-02-16T10:15:39.623236-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"provisioner":"local-exec","output":"Hello World!"},"type":"provision_progress"}
|
||||
{"@level":"info","@message":"null_resource.foo: (local-exec) Provisioning complete","@module":"terraform.ui","@timestamp":"2023-02-16T10:15:39.623275-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"provisioner":"local-exec"},"type":"provision_complete"}
|
||||
{"@level":"info","@message":"null_resource.foo: Creation complete after 0s [id=7836952171100801169]","@module":"terraform.ui","@timestamp":"2023-02-16T10:15:39.623320-05:00","hook":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"action":"create","id_key":"id","id_value":"7836952171100801169","elapsed_seconds":0},"type":"apply_complete"}
|
||||
{"@level":"info","@message":"Apply complete! Resources: 1 added, 0 changed, 1 destroyed.","@module":"terraform.ui","@timestamp":"2023-02-16T10:15:39.631098-05:00","changes":{"add":1,"change":0,"remove":1,"operation":"apply"},"type":"change_summary"}
|
||||
{"@level":"info","@message":"Outputs: 0","@module":"terraform.ui","@timestamp":"2023-02-16T10:15:39.631112-05:00","outputs":{},"type":"outputs"}
|
5
internal/cloud/testdata/apply-json-with-provisioner/main.tf
vendored
Normal file
5
internal/cloud/testdata/apply-json-with-provisioner/main.tf
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
resource "null_resource" "foo" {
|
||||
provisioner "local-exec" {
|
||||
command = "echo Hello World!"
|
||||
}
|
||||
}
|
116
internal/cloud/testdata/apply-json-with-provisioner/plan-redacted.json
vendored
Normal file
116
internal/cloud/testdata/apply-json-with-provisioner/plan-redacted.json
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
{
|
||||
"plan_format_version": "1.1",
|
||||
"resource_drift": [],
|
||||
"resource_changes": [
|
||||
{
|
||||
"address": "null_resource.foo",
|
||||
"mode": "managed",
|
||||
"type": "null_resource",
|
||||
"name": "foo",
|
||||
"provider_name": "registry.terraform.io/hashicorp/null",
|
||||
"change": {
|
||||
"actions": [
|
||||
"create"
|
||||
],
|
||||
"before": null,
|
||||
"after": {
|
||||
"triggers": null
|
||||
},
|
||||
"after_unknown": {
|
||||
"id": true
|
||||
},
|
||||
"before_sensitive": false,
|
||||
"after_sensitive": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"relevant_attributes": [],
|
||||
"output_changes": {},
|
||||
"provider_schemas": {
|
||||
"registry.terraform.io/hashicorp/null": {
|
||||
"provider": {
|
||||
"version": 0,
|
||||
"block": {
|
||||
"description_kind": "plain"
|
||||
}
|
||||
},
|
||||
"resource_schemas": {
|
||||
"null_resource": {
|
||||
"version": 0,
|
||||
"block": {
|
||||
"attributes": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "This is set to a random value at create time.",
|
||||
"description_kind": "plain",
|
||||
"computed": true
|
||||
},
|
||||
"triggers": {
|
||||
"type": [
|
||||
"map",
|
||||
"string"
|
||||
],
|
||||
"description": "A map of arbitrary strings that, when changed, will force the null resource to be replaced, re-running any associated provisioners.",
|
||||
"description_kind": "plain",
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"description": "The `null_resource` resource implements the standard resource lifecycle but takes no further action.\n\nThe `triggers` argument allows specifying an arbitrary set of values that, when changed, will cause the resource to be replaced.",
|
||||
"description_kind": "plain"
|
||||
}
|
||||
}
|
||||
},
|
||||
"data_source_schemas": {
|
||||
"null_data_source": {
|
||||
"version": 0,
|
||||
"block": {
|
||||
"attributes": {
|
||||
"has_computed_default": {
|
||||
"type": "string",
|
||||
"description": "If set, its literal value will be stored and returned. If not, its value defaults to `\"default\"`. This argument exists primarily for testing and has little practical use.",
|
||||
"description_kind": "plain",
|
||||
"optional": true,
|
||||
"computed": true
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "This attribute is only present for some legacy compatibility issues and should not be used. It will be removed in a future version.",
|
||||
"description_kind": "plain",
|
||||
"deprecated": true,
|
||||
"computed": true
|
||||
},
|
||||
"inputs": {
|
||||
"type": [
|
||||
"map",
|
||||
"string"
|
||||
],
|
||||
"description": "A map of arbitrary strings that is copied into the `outputs` attribute, and accessible directly for interpolation.",
|
||||
"description_kind": "plain",
|
||||
"optional": true
|
||||
},
|
||||
"outputs": {
|
||||
"type": [
|
||||
"map",
|
||||
"string"
|
||||
],
|
||||
"description": "After the data source is \"read\", a copy of the `inputs` map.",
|
||||
"description_kind": "plain",
|
||||
"computed": true
|
||||
},
|
||||
"random": {
|
||||
"type": "string",
|
||||
"description": "A random value. This is primarily for testing and has little practical use; prefer the [hashicorp/random provider](https://registry.terraform.io/providers/hashicorp/random) for more practical random number use-cases.",
|
||||
"description_kind": "plain",
|
||||
"computed": true
|
||||
}
|
||||
},
|
||||
"description": "The `null_data_source` data source implements the standard data source lifecycle but does not\ninteract with any external APIs.\n\nHistorically, the `null_data_source` was typically used to construct intermediate values to re-use elsewhere in configuration. The\nsame can now be achieved using [locals](https://www.terraform.io/docs/language/values/locals.html).\n",
|
||||
"description_kind": "plain",
|
||||
"deprecated": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"provider_format_version": "1.0"
|
||||
}
|
3
internal/cloud/testdata/apply-json-with-provisioner/plan.log
vendored
Normal file
3
internal/cloud/testdata/apply-json-with-provisioner/plan.log
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{"@level":"info","@message":"Terraform 1.3.7","@module":"terraform.ui","@timestamp":"2023-01-20T15:50:04.623068-05:00","terraform":"1.3.7","type":"version","ui":"1.0"}
|
||||
{"@level":"info","@message":"null_resource.foo: Plan to create","@module":"terraform.ui","@timestamp":"2023-01-20T15:50:04.822722-05:00","change":{"resource":{"addr":"null_resource.foo","module":"","resource":"null_resource.foo","implied_provider":"null","resource_type":"null_resource","resource_name":"foo","resource_key":null},"action":"create"},"type":"planned_change"}
|
||||
{"@level":"info","@message":"Plan: 1 to add, 0 to change, 0 to destroy.","@module":"terraform.ui","@timestamp":"2023-01-20T15:50:04.822787-05:00","changes":{"add":1,"change":0,"remove":0,"operation":"plan"},"type":"change_summary"}
|
@ -20,22 +20,28 @@ import (
|
||||
type JSONLogType string
|
||||
|
||||
type JSONLog struct {
|
||||
Message string `json:"@message"`
|
||||
Type JSONLogType `json:"type"`
|
||||
Diagnostic *viewsjson.Diagnostic `json:"diagnostic"`
|
||||
Outputs viewsjson.Outputs `json:"outputs"`
|
||||
Message string `json:"@message"`
|
||||
Type JSONLogType `json:"type"`
|
||||
Diagnostic *viewsjson.Diagnostic `json:"diagnostic"`
|
||||
Outputs viewsjson.Outputs `json:"outputs"`
|
||||
Hook map[string]interface{} `json:"hook"`
|
||||
}
|
||||
|
||||
const (
|
||||
LogVersion JSONLogType = "version"
|
||||
LogDiagnostic JSONLogType = "diagnostic"
|
||||
LogPlannedChange JSONLogType = "planned_change"
|
||||
LogRefreshStart JSONLogType = "refresh_start"
|
||||
LogRefreshComplete JSONLogType = "refresh_complete"
|
||||
LogApplyStart JSONLogType = "apply_start"
|
||||
LogApplyComplete JSONLogType = "apply_complete"
|
||||
LogChangeSummary JSONLogType = "change_summary"
|
||||
LogOutputs JSONLogType = "outputs"
|
||||
LogVersion JSONLogType = "version"
|
||||
LogDiagnostic JSONLogType = "diagnostic"
|
||||
LogPlannedChange JSONLogType = "planned_change"
|
||||
LogRefreshStart JSONLogType = "refresh_start"
|
||||
LogRefreshComplete JSONLogType = "refresh_complete"
|
||||
LogApplyStart JSONLogType = "apply_start"
|
||||
LogApplyErrored JSONLogType = "apply_errored"
|
||||
LogApplyComplete JSONLogType = "apply_complete"
|
||||
LogChangeSummary JSONLogType = "change_summary"
|
||||
LogProvisionStart JSONLogType = "provision_start"
|
||||
LogProvisionProgress JSONLogType = "provision_progress"
|
||||
LogProvisionComplete JSONLogType = "provision_complete"
|
||||
LogProvisionErrored JSONLogType = "provision_errored"
|
||||
LogOutputs JSONLogType = "outputs"
|
||||
)
|
||||
|
||||
type Renderer struct {
|
||||
@ -86,11 +92,16 @@ func (renderer Renderer) RenderHumanState(state State) {
|
||||
|
||||
func (r Renderer) RenderLog(log *JSONLog) error {
|
||||
switch log.Type {
|
||||
case LogRefreshComplete, LogVersion, LogPlannedChange:
|
||||
case LogRefreshComplete,
|
||||
LogVersion,
|
||||
LogPlannedChange,
|
||||
LogProvisionComplete,
|
||||
LogProvisionErrored,
|
||||
LogApplyErrored:
|
||||
// We won't display these types of logs
|
||||
return nil
|
||||
|
||||
case LogApplyStart, LogApplyComplete, LogRefreshStart:
|
||||
case LogApplyStart, LogApplyComplete, LogRefreshStart, LogProvisionStart:
|
||||
msg := fmt.Sprintf(r.Colorize.Color("[bold]%s[reset]"), log.Message)
|
||||
r.Streams.Println(msg)
|
||||
|
||||
@ -119,8 +130,18 @@ func (r Renderer) RenderLog(log *JSONLog) error {
|
||||
}
|
||||
}
|
||||
|
||||
case LogProvisionProgress:
|
||||
provisioner := log.Hook["provisioner"].(string)
|
||||
output := log.Hook["output"].(string)
|
||||
resource := log.Hook["resource"].(map[string]interface{})
|
||||
resourceAddr := resource["addr"].(string)
|
||||
|
||||
msg := fmt.Sprintf(r.Colorize.Color("[bold]%s: (%s):[reset] %s"),
|
||||
resourceAddr, provisioner, output)
|
||||
r.Streams.Println(msg)
|
||||
|
||||
case LogChangeSummary:
|
||||
// We will only render the apply change summary since the renderer
|
||||
// Normally, we will only render the apply change summary since the renderer
|
||||
// generates a plan change summary for us
|
||||
msg := fmt.Sprintf(r.Colorize.Color("[bold][green]%s[reset]"), log.Message)
|
||||
r.Streams.Println("\n" + msg + "\n")
|
||||
|
Loading…
Reference in New Issue
Block a user