@intentius/chant-lexicon-terraform 0.124.52 → 0.124.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -10
- package/dist/__fixtures__/pr-loop/estate.component.d.ts +7 -0
- package/dist/__fixtures__/pr-loop/estate.component.d.ts.map +1 -0
- package/dist/__fixtures__/pr-loop/estate.component.js +7 -0
- package/dist/__fixtures__/report/generate.d.ts +26 -0
- package/dist/__fixtures__/report/generate.d.ts.map +1 -0
- package/dist/__fixtures__/report/generate.js +58 -0
- package/dist/applied-state.d.ts +27 -0
- package/dist/applied-state.d.ts.map +1 -0
- package/dist/applied-state.js +44 -0
- package/dist/backend-config.d.ts +53 -0
- package/dist/backend-config.d.ts.map +1 -0
- package/dist/backend-config.js +136 -0
- package/dist/behaviour/kinds.d.ts.map +1 -1
- package/dist/behaviour/kinds.js +4 -0
- package/dist/behaviour/predict.d.ts.map +1 -1
- package/dist/behaviour/predict.js +6 -2
- package/dist/behaviour/reference-catalog.d.ts +16 -5
- package/dist/behaviour/reference-catalog.d.ts.map +1 -1
- package/dist/behaviour/reference-catalog.js +16 -5
- package/dist/behaviour/request.d.ts.map +1 -1
- package/dist/behaviour/request.js +3 -2
- package/dist/changed-roots.d.ts +6 -4
- package/dist/changed-roots.d.ts.map +1 -1
- package/dist/changed-roots.js +14 -18
- package/dist/ci-setup.d.ts +11 -0
- package/dist/ci-setup.d.ts.map +1 -0
- package/dist/ci-setup.js +41 -0
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +4 -3
- package/dist/components/capability-plugin.d.ts +105 -9
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/capability-plugin.js +357 -36
- package/dist/components/compose-group.d.ts +145 -0
- package/dist/components/compose-group.d.ts.map +1 -0
- package/dist/components/compose-group.js +407 -0
- package/dist/components/placeholder-preview.d.ts +78 -0
- package/dist/components/placeholder-preview.d.ts.map +1 -0
- package/dist/components/placeholder-preview.js +254 -0
- package/dist/components/release-inputs.d.ts +29 -0
- package/dist/components/release-inputs.d.ts.map +1 -0
- package/dist/components/release-inputs.js +57 -0
- package/dist/components/trace-facts.d.ts +16 -0
- package/dist/components/trace-facts.d.ts.map +1 -0
- package/dist/components/trace-facts.js +19 -0
- package/dist/compose/apply-events.d.ts +46 -0
- package/dist/compose/apply-events.d.ts.map +1 -0
- package/dist/compose/apply-events.js +77 -0
- package/dist/compose/estate.d.ts +194 -0
- package/dist/compose/estate.d.ts.map +1 -0
- package/dist/compose/estate.js +363 -0
- package/dist/compose/hcl.d.ts +99 -0
- package/dist/compose/hcl.d.ts.map +1 -0
- package/dist/compose/hcl.js +302 -0
- package/dist/compose/module-address.d.ts +24 -0
- package/dist/compose/module-address.d.ts.map +1 -0
- package/dist/compose/module-address.js +43 -0
- package/dist/compose/root.d.ts +127 -0
- package/dist/compose/root.d.ts.map +1 -0
- package/dist/compose/root.js +586 -0
- package/dist/compose/run.d.ts +183 -0
- package/dist/compose/run.d.ts.map +1 -0
- package/dist/compose/run.js +447 -0
- package/dist/compose/slice.d.ts +102 -0
- package/dist/compose/slice.d.ts.map +1 -0
- package/dist/compose/slice.js +249 -0
- package/dist/compose/state-address.d.ts +28 -0
- package/dist/compose/state-address.d.ts.map +1 -0
- package/dist/compose/state-address.js +154 -0
- package/dist/compose/state-merge.d.ts +52 -0
- package/dist/compose/state-merge.d.ts.map +1 -0
- package/dist/compose/state-merge.js +135 -0
- package/dist/compose.d.ts +179 -0
- package/dist/compose.d.ts.map +1 -0
- package/dist/compose.js +482 -0
- package/dist/composites/terraform-apply-op.d.ts.map +1 -1
- package/dist/composites/terraform-apply-op.js +7 -3
- package/dist/cone.d.ts +53 -0
- package/dist/cone.d.ts.map +1 -0
- package/dist/cone.js +119 -0
- package/dist/config.d.ts +59 -13
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -9
- package/dist/cost-hold.d.ts +27 -0
- package/dist/cost-hold.d.ts.map +1 -0
- package/dist/cost-hold.js +21 -0
- package/dist/describe-resources.d.ts +74 -12
- package/dist/describe-resources.d.ts.map +1 -1
- package/dist/describe-resources.js +374 -66
- package/dist/drift-read.d.ts +33 -0
- package/dist/drift-read.d.ts.map +1 -0
- package/dist/drift-read.js +243 -0
- package/dist/drift-record.d.ts +147 -0
- package/dist/drift-record.d.ts.map +1 -0
- package/dist/drift-record.js +383 -0
- package/dist/drift-rows.d.ts +61 -0
- package/dist/drift-rows.d.ts.map +1 -0
- package/dist/drift-rows.js +108 -0
- package/dist/exit-codes.d.ts +55 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +48 -0
- package/dist/hcl/edges.d.ts.map +1 -1
- package/dist/hcl/edges.js +24 -1
- package/dist/hcl/files.d.ts +61 -0
- package/dist/hcl/files.d.ts.map +1 -0
- package/dist/hcl/files.js +221 -0
- package/dist/hcl/instances.d.ts +82 -0
- package/dist/hcl/instances.d.ts.map +1 -0
- package/dist/hcl/instances.js +390 -0
- package/dist/hcl/parse.d.ts +81 -9
- package/dist/hcl/parse.d.ts.map +1 -1
- package/dist/hcl/parse.js +114 -16
- package/dist/hcl/roots.d.ts.map +1 -1
- package/dist/hcl/roots.js +5 -0
- package/dist/hcl/suppressions.d.ts.map +1 -1
- package/dist/hcl/suppressions.js +8 -2
- package/dist/index.d.ts +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -2
- package/dist/integrity.json +8 -5
- package/dist/lint/audit-catalog.d.ts.map +1 -1
- package/dist/lint/audit-catalog.js +27 -3
- package/dist/lint/audit-lineage.d.ts +14 -2
- package/dist/lint/audit-lineage.d.ts.map +1 -1
- package/dist/lint/post-synth/index.d.ts.map +1 -1
- package/dist/lint/post-synth/index.js +4 -0
- package/dist/lint/post-synth/record-store.d.ts +54 -0
- package/dist/lint/post-synth/record-store.d.ts.map +1 -0
- package/dist/lint/post-synth/record-store.js +104 -0
- package/dist/lint/post-synth/tf001.d.ts +2 -2
- package/dist/lint/post-synth/tf001.js +2 -2
- package/dist/lint/post-synth/tf024.d.ts +35 -11
- package/dist/lint/post-synth/tf024.d.ts.map +1 -1
- package/dist/lint/post-synth/tf024.js +92 -20
- package/dist/lint/post-synth/tf046.d.ts +64 -0
- package/dist/lint/post-synth/tf046.d.ts.map +1 -0
- package/dist/lint/post-synth/tf046.js +175 -0
- package/dist/lint/post-synth/tf047.d.ts +36 -0
- package/dist/lint/post-synth/tf047.d.ts.map +1 -0
- package/dist/lint/post-synth/tf047.js +94 -0
- package/dist/live-plan-reasons.d.ts +21 -0
- package/dist/live-plan-reasons.d.ts.map +1 -0
- package/dist/live-plan-reasons.js +47 -0
- package/dist/lock-rows.d.ts +36 -0
- package/dist/lock-rows.d.ts.map +1 -0
- package/dist/lock-rows.js +60 -0
- package/dist/lock-timeout.d.ts +22 -0
- package/dist/lock-timeout.d.ts.map +1 -0
- package/dist/lock-timeout.js +32 -0
- package/dist/lsp/option-keys.d.ts.map +1 -1
- package/dist/lsp/option-keys.js +2 -0
- package/dist/manifest.json +1 -1
- package/dist/module-catalog/index.d.ts +69 -0
- package/dist/module-catalog/index.d.ts.map +1 -0
- package/dist/module-catalog/index.js +110 -0
- package/dist/module-catalog/refresh-cli.d.ts +4 -0
- package/dist/module-catalog/refresh-cli.d.ts.map +1 -0
- package/dist/module-catalog/refresh-cli.js +64 -0
- package/dist/module-catalog/static-tier.d.ts +6 -0
- package/dist/module-catalog/static-tier.d.ts.map +1 -0
- package/dist/module-catalog/static-tier.js +1650 -0
- package/dist/module-catalog/types.d.ts +65 -0
- package/dist/module-catalog/types.d.ts.map +1 -0
- package/dist/module-catalog/types.js +33 -0
- package/dist/okf/index.md +3 -1
- package/dist/okf/rules/TF024.md +2 -2
- package/dist/okf/rules/TF046.md +11 -0
- package/dist/okf/rules/TF047.md +11 -0
- package/dist/op/activities/index.d.ts +6 -2
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/index.js +5 -1
- package/dist/op/activities/live-detect.d.ts +4 -3
- package/dist/op/activities/live-detect.d.ts.map +1 -1
- package/dist/op/activities/live-detect.js +57 -32
- package/dist/op/activities/pin-rollout.d.ts +2 -0
- package/dist/op/activities/pin-rollout.d.ts.map +1 -1
- package/dist/op/activities/pin-rollout.js +1 -0
- package/dist/op/activities/terraform.d.ts +182 -5
- package/dist/op/activities/terraform.d.ts.map +1 -1
- package/dist/op/activities/terraform.js +224 -24
- package/dist/op/activity-contracts.d.ts +27 -0
- package/dist/op/activity-contracts.d.ts.map +1 -1
- package/dist/op/activity-contracts.js +19 -1
- package/dist/op/builders.d.ts +7 -1
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +9 -0
- package/dist/pin/consumers.d.ts +35 -0
- package/dist/pin/consumers.d.ts.map +1 -0
- package/dist/pin/consumers.js +70 -0
- package/dist/pin/edit.d.ts.map +1 -1
- package/dist/pin/edit.js +35 -0
- package/dist/pin/rollout.d.ts +2 -0
- package/dist/pin/rollout.d.ts.map +1 -1
- package/dist/pin/rollout.js +14 -11
- package/dist/plan-shape.d.ts +30 -0
- package/dist/plan-shape.d.ts.map +1 -0
- package/dist/plan-shape.js +125 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +37 -18
- package/dist/registry/address.d.ts +63 -0
- package/dist/registry/address.d.ts.map +1 -0
- package/dist/registry/address.js +65 -0
- package/dist/registry/catalog-read.d.ts +14 -0
- package/dist/registry/catalog-read.d.ts.map +1 -0
- package/dist/registry/catalog-read.js +58 -0
- package/dist/registry/deprecated.d.ts +37 -0
- package/dist/registry/deprecated.d.ts.map +1 -0
- package/dist/registry/deprecated.js +43 -0
- package/dist/registry/docs.d.ts +96 -0
- package/dist/registry/docs.d.ts.map +1 -0
- package/dist/registry/docs.js +210 -0
- package/dist/registry/edge/edge.d.ts +46 -0
- package/dist/registry/edge/edge.d.ts.map +1 -0
- package/dist/registry/edge/edge.js +194 -0
- package/dist/registry/edge/index.d.ts +11 -0
- package/dist/registry/edge/index.d.ts.map +1 -0
- package/dist/registry/edge/index.js +10 -0
- package/dist/registry/edge/lambda-edge.d.ts +76 -0
- package/dist/registry/edge/lambda-edge.d.ts.map +1 -0
- package/dist/registry/edge/lambda-edge.js +95 -0
- package/dist/registry/edge/sigv4-web.d.ts +33 -0
- package/dist/registry/edge/sigv4-web.d.ts.map +1 -0
- package/dist/registry/edge/sigv4-web.js +56 -0
- package/dist/registry/edge/token-source.d.ts +73 -0
- package/dist/registry/edge/token-source.d.ts.map +1 -0
- package/dist/registry/edge/token-source.js +115 -0
- package/dist/registry/edge/worker.d.ts +45 -0
- package/dist/registry/edge/worker.d.ts.map +1 -0
- package/dist/registry/edge/worker.js +26 -0
- package/dist/registry/handler.d.ts +25 -0
- package/dist/registry/handler.d.ts.map +1 -0
- package/dist/registry/handler.js +75 -0
- package/dist/registry/headers-file.d.ts +21 -0
- package/dist/registry/headers-file.d.ts.map +1 -0
- package/dist/registry/headers-file.js +57 -0
- package/dist/registry/index.d.ts +31 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +30 -0
- package/dist/registry/mirror-paths.d.ts +9 -0
- package/dist/registry/mirror-paths.d.ts.map +1 -0
- package/dist/registry/mirror-paths.js +8 -0
- package/dist/registry/mirror.d.ts +130 -0
- package/dist/registry/mirror.d.ts.map +1 -0
- package/dist/registry/mirror.js +319 -0
- package/dist/registry/proxies.d.ts +73 -0
- package/dist/registry/proxies.d.ts.map +1 -0
- package/dist/registry/proxies.js +111 -0
- package/dist/registry/reader.d.ts +57 -0
- package/dist/registry/reader.d.ts.map +1 -0
- package/dist/registry/reader.js +198 -0
- package/dist/registry/semver.d.ts +16 -0
- package/dist/registry/semver.d.ts.map +1 -0
- package/dist/registry/semver.js +24 -0
- package/dist/registry/serve.d.ts +24 -0
- package/dist/registry/serve.d.ts.map +1 -0
- package/dist/registry/serve.js +64 -0
- package/dist/registry/source-forms.d.ts +79 -0
- package/dist/registry/source-forms.d.ts.map +1 -0
- package/dist/registry/source-forms.js +202 -0
- package/dist/registry/targets/artifactory.d.ts +28 -0
- package/dist/registry/targets/artifactory.d.ts.map +1 -0
- package/dist/registry/targets/artifactory.js +206 -0
- package/dist/registry/targets/fake-artifactory.d.ts +30 -0
- package/dist/registry/targets/fake-artifactory.d.ts.map +1 -0
- package/dist/registry/targets/fake-artifactory.js +142 -0
- package/dist/registry/targets/fake-gitlab.d.ts +39 -0
- package/dist/registry/targets/fake-gitlab.d.ts.map +1 -0
- package/dist/registry/targets/fake-gitlab.js +136 -0
- package/dist/registry/targets/fake-hcp.d.ts +50 -0
- package/dist/registry/targets/fake-hcp.d.ts.map +1 -0
- package/dist/registry/targets/fake-hcp.js +202 -0
- package/dist/registry/targets/fake-http.d.ts +31 -0
- package/dist/registry/targets/fake-http.d.ts.map +1 -0
- package/dist/registry/targets/fake-http.js +87 -0
- package/dist/registry/targets/fake-nexus.d.ts +27 -0
- package/dist/registry/targets/fake-nexus.d.ts.map +1 -0
- package/dist/registry/targets/fake-nexus.js +137 -0
- package/dist/registry/targets/gitlab.d.ts +53 -0
- package/dist/registry/targets/gitlab.d.ts.map +1 -0
- package/dist/registry/targets/gitlab.js +187 -0
- package/dist/registry/targets/hcp.d.ts +29 -0
- package/dist/registry/targets/hcp.d.ts.map +1 -0
- package/dist/registry/targets/hcp.js +310 -0
- package/dist/registry/targets/hosted.d.ts +62 -0
- package/dist/registry/targets/hosted.d.ts.map +1 -0
- package/dist/registry/targets/hosted.js +74 -0
- package/dist/registry/targets/index.d.ts +18 -0
- package/dist/registry/targets/index.d.ts.map +1 -0
- package/dist/registry/targets/index.js +17 -0
- package/dist/registry/targets/module-target.d.ts +68 -0
- package/dist/registry/targets/module-target.d.ts.map +1 -0
- package/dist/registry/targets/module-target.js +63 -0
- package/dist/registry/targets/nexus.d.ts +43 -0
- package/dist/registry/targets/nexus.d.ts.map +1 -0
- package/dist/registry/targets/nexus.js +250 -0
- package/dist/registry/targets/zip.d.ts +55 -0
- package/dist/registry/targets/zip.d.ts.map +1 -0
- package/dist/registry/targets/zip.js +278 -0
- package/dist/registry/writer.d.ts +101 -0
- package/dist/registry/writer.d.ts.map +1 -0
- package/dist/registry/writer.js +109 -0
- package/dist/report.d.ts +15 -6
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +28 -55
- package/dist/rules/record-store.ts +122 -0
- package/dist/rules/tf001.ts +2 -2
- package/dist/rules/tf024.ts +105 -22
- package/dist/rules/tf046.ts +204 -0
- package/dist/rules/tf047.ts +114 -0
- package/dist/skills/chant-terraform.md +1 -1
- package/dist/state/azure-blob.d.ts +9 -0
- package/dist/state/azure-blob.d.ts.map +1 -0
- package/dist/state/azure-blob.js +8 -0
- package/dist/state/backend.d.ts +158 -0
- package/dist/state/backend.d.ts.map +1 -0
- package/dist/state/backend.js +406 -0
- package/dist/state/exec.d.ts +39 -0
- package/dist/state/exec.d.ts.map +1 -0
- package/dist/state/exec.js +80 -0
- package/dist/state/gcs.d.ts +8 -0
- package/dist/state/gcs.d.ts.map +1 -0
- package/dist/state/gcs.js +7 -0
- package/dist/state/index.d.ts +15 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +14 -0
- package/dist/state/locks.d.ts +105 -0
- package/dist/state/locks.d.ts.map +1 -0
- package/dist/state/locks.js +130 -0
- package/dist/state/object-store.d.ts +8 -0
- package/dist/state/object-store.d.ts.map +1 -0
- package/dist/state/object-store.js +7 -0
- package/dist/state/root-states.d.ts +131 -0
- package/dist/state/root-states.d.ts.map +1 -0
- package/dist/state/root-states.js +241 -0
- package/dist/state/s3.d.ts +21 -0
- package/dist/state/s3.d.ts.map +1 -0
- package/dist/state/s3.js +19 -0
- package/dist/state/store.d.ts +51 -0
- package/dist/state/store.d.ts.map +1 -0
- package/dist/state/store.js +185 -0
- package/dist/state-ops.d.ts +255 -0
- package/dist/state-ops.d.ts.map +1 -0
- package/dist/state-ops.js +305 -0
- package/dist/state-reads.d.ts +57 -0
- package/dist/state-reads.d.ts.map +1 -0
- package/dist/state-reads.js +104 -0
- package/dist/terragrunt/affected.d.ts.map +1 -1
- package/dist/terragrunt/affected.js +2 -1
- package/dist/used-sources.d.ts +54 -0
- package/dist/used-sources.d.ts.map +1 -0
- package/dist/used-sources.js +157 -0
- package/package.json +24 -4
- package/src/__fixtures__/ACCEPTANCE.md +69 -7
- package/src/__fixtures__/compose/apply-failed-in-app.jsonl +12 -0
- package/src/__fixtures__/compose/state-app.json +66 -0
- package/src/__fixtures__/compose/state-edge.json +40 -0
- package/src/__fixtures__/compose/state-net.json +58 -0
- package/src/__fixtures__/compose/three-app.plan.json +184 -0
- package/src/__fixtures__/compose/three-composed.plan.json +509 -0
- package/src/__fixtures__/compose/three-edge.plan.json +144 -0
- package/src/__fixtures__/compose/three-net.plan.json +174 -0
- package/src/__fixtures__/compose/unknown-composed.plan.json +228 -0
- package/src/__fixtures__/compose/working-after-apply.json +145 -0
- package/src/__fixtures__/config-blocks/app/main.tf +61 -0
- package/src/__fixtures__/config-blocks/app/modules/network/main.tf +4 -0
- package/src/__fixtures__/config-blocks/app-json/main.tf.json +39 -0
- package/src/__fixtures__/config-files/shadow/main.tf +3 -0
- package/src/__fixtures__/config-files/shadow/main.tofu +3 -0
- package/src/__fixtures__/config-files/shadow/other.tf +3 -0
- package/src/__fixtures__/config-files/tf/main.tf +11 -0
- package/src/__fixtures__/config-files/tf-json/main.tf.json +18 -0
- package/src/__fixtures__/config-files/tofu/main.tofu +11 -0
- package/src/__fixtures__/config-files/tofu-json/main.tofu.json +18 -0
- package/src/__fixtures__/config-files/tofu-only/main.tofu +3 -0
- package/src/__fixtures__/drift-record/README.md +16 -0
- package/src/__fixtures__/drift-record/live-plan-sections.json +27 -0
- package/src/__fixtures__/drift-rows/live-root-plan.json +70 -0
- package/src/__fixtures__/drift-rows/refresh-plan.json +61 -0
- package/src/__fixtures__/instance-forms/app/main.tf +110 -0
- package/src/__fixtures__/instance-forms/app/modules/svc/main.tf +3 -0
- package/src/__fixtures__/instance-vars/app/main.tf +52 -0
- package/src/__fixtures__/instance-vars/app/modules/app/main.tf +12 -0
- package/src/__fixtures__/instance-vars/app/modules/edge/main.tf +3 -0
- package/src/__fixtures__/instance-vars/app/terraform.tfvars +1 -0
- package/src/__fixtures__/live-module-keyed/live-graph.json +259 -0
- package/src/__fixtures__/live-module-keyed/live-plan.json +87 -0
- package/src/__fixtures__/live-module-keyed/root/estate.chdf.hcl +1 -0
- package/src/__fixtures__/live-module-keyed/root/main.tf +21 -0
- package/src/__fixtures__/live-module-keyed/root/modules/app/main.tf +17 -0
- package/src/__fixtures__/live-module-keyed/root/modules/edge/main.tf +7 -0
- package/src/__fixtures__/live-module-keyed/root/versions.tf +30 -0
- package/src/__fixtures__/live-module-keyed/show-state.json +146 -0
- package/src/__fixtures__/pr-loop/README.md +50 -0
- package/src/__fixtures__/pr-loop/chant.config.json +13 -0
- package/src/__fixtures__/pr-loop/estate.component.ts +10 -0
- package/src/__fixtures__/pr-loop/roots/a/main.tf +11 -0
- package/src/__fixtures__/pr-loop/roots/app/main.tf +19 -0
- package/src/__fixtures__/pr-loop/roots/b/main.tf +7 -0
- package/src/__fixtures__/pr-loop/roots/dns/main.tf +3 -0
- package/src/__fixtures__/pr-loop/roots/net/main.tf +7 -0
- package/src/__fixtures__/report/applied.show.json +51 -0
- package/src/__fixtures__/report/generate.ts +63 -0
- package/src/__fixtures__/report/plan.show.json +200 -0
- package/src/__fixtures__/report/tf-apply/change-set.json +170 -0
- package/src/__fixtures__/report/tf-apply/report.json +338 -0
- package/src/__fixtures__/report/tf-plan/change-set.json +170 -0
- package/src/__fixtures__/report/tf-plan/report.json +320 -0
- package/src/__fixtures__/three-cloud-azure.graph.json +290 -0
- package/src/__fixtures__/used-sources/root/extra.tofu +1 -0
- package/src/__fixtures__/used-sources/root/main.tf +31 -0
- package/src/__fixtures__/used-sources/root/modules/net/main.tf +14 -0
- package/src/__fixtures__/used-sources/root/modules/net/versions.tf.json +7 -0
- package/src/__fixtures__/used-sources/unit/terragrunt.hcl +3 -0
- package/src/applied-state.ts +52 -0
- package/src/backend-config.test.ts +105 -0
- package/src/backend-config.ts +133 -0
- package/src/behaviour/kinds.ts +4 -0
- package/src/behaviour/predict.ts +5 -2
- package/src/behaviour/reference-catalog.plugin.test.ts +65 -0
- package/src/behaviour/reference-catalog.ts +16 -5
- package/src/behaviour/request.ts +3 -2
- package/src/change-set-instances.test.ts +98 -0
- package/src/changed-roots.ts +14 -16
- package/src/ci-setup.ts +42 -0
- package/src/commands.ts +4 -3
- package/src/components/capability-plugin.test.ts +198 -19
- package/src/components/capability-plugin.ts +383 -35
- package/src/components/change-set-graph.e2e.test.ts +11 -5
- package/src/components/compose-group.test.ts +486 -0
- package/src/components/compose-group.ts +489 -0
- package/src/components/demo-composed-roots.e2e.test.ts +440 -0
- package/src/components/member-outputs.test.ts +76 -0
- package/src/components/placeholder-preview.test.ts +147 -0
- package/src/components/placeholder-preview.ts +257 -0
- package/src/components/pr-loop-compose.tofu.e2e.test.ts +363 -0
- package/src/components/pr-loop.tofu.test.ts +113 -57
- package/src/components/release-inputs.ts +69 -0
- package/src/components/trace-facts.test.ts +21 -0
- package/src/components/trace-facts.ts +27 -0
- package/src/compose/apply-events.test.ts +62 -0
- package/src/compose/apply-events.ts +100 -0
- package/src/compose/estate.choudoufu.e2e.test.ts +112 -0
- package/src/compose/estate.test.ts +421 -0
- package/src/compose/estate.ts +443 -0
- package/src/compose/hcl.ts +311 -0
- package/src/compose/module-address.ts +49 -0
- package/src/compose/root.test.ts +416 -0
- package/src/compose/root.ts +592 -0
- package/src/compose/run.test.ts +440 -0
- package/src/compose/run.tofu.test.ts +176 -0
- package/src/compose/run.ts +527 -0
- package/src/compose/slice.test.ts +184 -0
- package/src/compose/slice.ts +290 -0
- package/src/compose/state-address.ts +157 -0
- package/src/compose/state-merge.test.ts +131 -0
- package/src/compose/state-merge.ts +148 -0
- package/src/compose.test.ts +248 -0
- package/src/compose.ts +627 -0
- package/src/composites/terraform-apply-op.test.ts +9 -0
- package/src/composites/terraform-apply-op.ts +7 -3
- package/src/cone.ts +138 -0
- package/src/config-file-listers.test.ts +265 -0
- package/src/config.ts +44 -9
- package/src/cost-hold.ts +29 -0
- package/src/describe-resources.engine-facts.test.ts +411 -0
- package/src/describe-resources.live-module-keyed.test.ts +290 -0
- package/src/describe-resources.ts +416 -70
- package/src/drift-read.ts +284 -0
- package/src/drift-record.test.ts +223 -0
- package/src/drift-record.ts +455 -0
- package/src/drift-rows.test.ts +135 -0
- package/src/drift-rows.ts +137 -0
- package/src/exit-codes.test.ts +23 -0
- package/src/exit-codes.ts +59 -0
- package/src/hcl/config-blocks.test.ts +174 -0
- package/src/hcl/edges.ts +21 -1
- package/src/hcl/files.ts +234 -0
- package/src/hcl/instance-forms.test.ts +94 -0
- package/src/hcl/instances.test.ts +137 -0
- package/src/hcl/instances.ts +422 -0
- package/src/hcl/parse.test.ts +139 -1
- package/src/hcl/parse.ts +149 -16
- package/src/hcl/roots.ts +6 -0
- package/src/hcl/suppressions.ts +8 -2
- package/src/index.ts +79 -0
- package/src/lint/audit-catalog.ts +29 -3
- package/src/lint/audit-lineage.ts +14 -2
- package/src/lint/post-synth/fixtures/TF024/live-with-record-store/main.tf +18 -0
- package/src/lint/post-synth/fixtures/TF024/sidecar-with-backend/estate.chdf.hcl +1 -0
- package/src/lint/post-synth/fixtures/TF024/sidecar-with-backend/main.tf +10 -0
- package/src/lint/post-synth/fixtures/TF046/azurerm-no-resource-group/main.tf +15 -0
- package/src/lint/post-synth/fixtures/TF046/backend-config-only/main.tf +14 -0
- package/src/lint/post-synth/fixtures/TF046/derived-s3/backend.tf +7 -0
- package/src/lint/post-synth/fixtures/TF046/derived-s3/main.tf +9 -0
- package/src/lint/post-synth/fixtures/TF046/explicit-local/main.tf +16 -0
- package/src/lint/post-synth/fixtures/TF046/explicit-s3-beside-local-backend/main.tf +15 -0
- package/src/lint/post-synth/fixtures/TF046/implied-local/main.tf +9 -0
- package/src/lint/post-synth/fixtures/TF046/sidecar-implied/estate.chdf.hcl +1 -0
- package/src/lint/post-synth/fixtures/TF046/sidecar-implied/main.tf +5 -0
- package/src/lint/post-synth/fixtures/TF047/clear/main.tf +12 -0
- package/src/lint/post-synth/fixtures/TF047/refused/main.tf +12 -0
- package/src/lint/post-synth/fixtures/TF047/unknown-module/main.tf +12 -0
- package/src/lint/post-synth/fixtures/TF047/unknown-version/main.tf +12 -0
- package/src/lint/post-synth/index.ts +4 -0
- package/src/lint/post-synth/record-store.ts +122 -0
- package/src/lint/post-synth/tf001.ts +2 -2
- package/src/lint/post-synth/tf024.test.ts +26 -5
- package/src/lint/post-synth/tf024.ts +105 -22
- package/src/lint/post-synth/tf046.test.ts +137 -0
- package/src/lint/post-synth/tf046.ts +204 -0
- package/src/lint/post-synth/tf047.test.ts +56 -0
- package/src/lint/post-synth/tf047.ts +114 -0
- package/src/live-plan-reasons.ts +54 -0
- package/src/lock-rows.test.ts +70 -0
- package/src/lock-rows.ts +82 -0
- package/src/lock-timeout.ts +34 -0
- package/src/lsp/completions.test.ts +1 -1
- package/src/lsp/option-keys.ts +2 -0
- package/src/module-catalog/index.test.ts +93 -0
- package/src/module-catalog/index.ts +159 -0
- package/src/module-catalog/refresh-cli.ts +68 -0
- package/src/module-catalog/static-tier.ts +1659 -0
- package/src/module-catalog/types.ts +88 -0
- package/src/op/activities/choudoufu-plan-set-op.test.ts +111 -0
- package/src/op/activities/index.ts +9 -0
- package/src/op/activities/live-detect.ts +55 -26
- package/src/op/activities/pin-rollout.ts +3 -0
- package/src/op/activities/registry.test.ts +2 -1
- package/src/op/activities/terraform.test.ts +55 -0
- package/src/op/activities/terraform.ts +312 -27
- package/src/op/activity-contracts.test.ts +1 -0
- package/src/op/activity-contracts.ts +24 -1
- package/src/op/builders.ts +14 -0
- package/src/op-wave-step.test.ts +109 -0
- package/src/pin/__fixtures__/consumers/live/dev/main.tf +4 -0
- package/src/pin/__fixtures__/consumers/live/prod/main.tf +21 -0
- package/src/pin/__fixtures__/consumers/units/vpc/terragrunt.hcl +7 -0
- package/src/pin/bundle.test.ts +2 -0
- package/src/pin/consumers.test.ts +57 -0
- package/src/pin/consumers.ts +95 -0
- package/src/pin/edit.ts +30 -0
- package/src/pin/rollout.ts +16 -11
- package/src/plan-shape.test.ts +148 -0
- package/src/plan-shape.ts +128 -0
- package/src/plugin.ts +39 -19
- package/src/registry/__fixtures__/docs/documented/.terraform-docs.yml +3 -0
- package/src/registry/__fixtures__/docs/documented/README.md +1 -0
- package/src/registry/__fixtures__/docs/documented/main.tf +8 -0
- package/src/registry/__fixtures__/docs/json/main.tf.json +14 -0
- package/src/registry/__fixtures__/docs/vpc/README.md +3 -0
- package/src/registry/__fixtures__/docs/vpc/examples/complete/main.tf +5 -0
- package/src/registry/__fixtures__/docs/vpc/examples/simple/README.md +1 -0
- package/src/registry/__fixtures__/docs/vpc/examples/simple/main.tf +4 -0
- package/src/registry/__fixtures__/docs/vpc/main.tf +14 -0
- package/src/registry/__fixtures__/docs/vpc/outputs.tf +9 -0
- package/src/registry/__fixtures__/docs/vpc/variables.tf +16 -0
- package/src/registry/__fixtures__/proxied-root/main.tf +12 -0
- package/src/registry/address.ts +100 -0
- package/src/registry/catalog-read.ts +56 -0
- package/src/registry/deprecated.test.ts +139 -0
- package/src/registry/deprecated.ts +76 -0
- package/src/registry/docs.test.ts +140 -0
- package/src/registry/docs.ts +299 -0
- package/src/registry/edge/bundle.test.ts +50 -0
- package/src/registry/edge/edge.test.ts +176 -0
- package/src/registry/edge/edge.ts +211 -0
- package/src/registry/edge/index.ts +10 -0
- package/src/registry/edge/lambda-edge.ts +127 -0
- package/src/registry/edge/sigv4-web.ts +79 -0
- package/src/registry/edge/token-source.test.ts +258 -0
- package/src/registry/edge/token-source.ts +169 -0
- package/src/registry/edge/worker.ts +61 -0
- package/src/registry/handler.ts +89 -0
- package/src/registry/headers-file.ts +61 -0
- package/src/registry/index.ts +31 -0
- package/src/registry/mirror-paths.ts +10 -0
- package/src/registry/mirror.test.ts +198 -0
- package/src/registry/mirror.ts +395 -0
- package/src/registry/proxies.test.ts +153 -0
- package/src/registry/proxies.ts +132 -0
- package/src/registry/reader.ts +225 -0
- package/src/registry/registry.test.ts +262 -0
- package/src/registry/semver.ts +34 -0
- package/src/registry/serve.ts +82 -0
- package/src/registry/source-forms.test.ts +87 -0
- package/src/registry/source-forms.ts +216 -0
- package/src/registry/targets/artifactory.test.ts +248 -0
- package/src/registry/targets/artifactory.ts +257 -0
- package/src/registry/targets/fake-artifactory.ts +158 -0
- package/src/registry/targets/fake-gitlab.ts +161 -0
- package/src/registry/targets/fake-hcp.ts +233 -0
- package/src/registry/targets/fake-http.ts +97 -0
- package/src/registry/targets/fake-nexus.ts +152 -0
- package/src/registry/targets/gitlab.test.ts +208 -0
- package/src/registry/targets/gitlab.ts +223 -0
- package/src/registry/targets/hcp.test.ts +230 -0
- package/src/registry/targets/hcp.ts +360 -0
- package/src/registry/targets/hosted.ts +117 -0
- package/src/registry/targets/index.ts +17 -0
- package/src/registry/targets/module-target.ts +131 -0
- package/src/registry/targets/nexus.test.ts +220 -0
- package/src/registry/targets/nexus.ts +314 -0
- package/src/registry/targets/zip.test.ts +65 -0
- package/src/registry/targets/zip.ts +287 -0
- package/src/registry/writer.ts +155 -0
- package/src/report.test.ts +82 -1
- package/src/report.ts +31 -54
- package/src/signal-only-root.test.ts +72 -0
- package/src/skills/chant-terraform.md +1 -1
- package/src/state/azure-blob.ts +8 -0
- package/src/state/backend-verdict.test.ts +187 -0
- package/src/state/backend.test.ts +127 -0
- package/src/state/backend.ts +488 -0
- package/src/state/exec.ts +111 -0
- package/src/state/gcs.ts +7 -0
- package/src/state/index.ts +15 -0
- package/src/state/locks.test.ts +84 -0
- package/src/state/locks.ts +201 -0
- package/src/state/object-store.ts +7 -0
- package/src/state/root-states-floci.e2e.test.ts +66 -0
- package/src/state/root-states.test.ts +462 -0
- package/src/state/root-states.ts +309 -0
- package/src/state/s3.ts +21 -0
- package/src/state/store.ts +225 -0
- package/src/state-ops.test.ts +182 -0
- package/src/state-ops.ts +462 -0
- package/src/state-reads.ts +116 -0
- package/src/terragrunt/affected.ts +2 -1
- package/src/used-sources.test.ts +75 -0
- package/src/used-sources.ts +204 -0
- package/src/workspace-kinds.test.ts +4 -17
- package/workspace-kinds.json +1 -24
- package/dist/workspace-member.d.ts +0 -30
- package/dist/workspace-member.d.ts.map +0 -1
- package/dist/workspace-member.js +0 -91
- package/schemas/pulumi.schema.json +0 -34
- package/src/testdata/pulumi-member/Pulumi.yaml +0 -2
- package/src/testdata/pulumi-member/stack-export.json +0 -53
- package/src/testdata/pulumi-unexported/Pulumi.yaml +0 -2
- package/src/workspace-member.test.ts +0 -89
- package/src/workspace-member.ts +0 -126
|
@@ -120,6 +120,14 @@
|
|
|
120
120
|
* not-observed, then foreign, then adoptable, then owned, and a block whose
|
|
121
121
|
* instances are all absent is absent. Partial knowledge is not knowledge,
|
|
122
122
|
* which is the same rule choudoufu applies to its own `INCOMPLETE_BLOCK`.
|
|
123
|
+
* The precedence is core's `TERRAFORM_INSTANCE_ROLLUP` and the rollup is
|
|
124
|
+
* core's `rollupInstances` (`@intentius/chant/instance-nodes`, #4454), the
|
|
125
|
+
* one place it is written.
|
|
126
|
+
*
|
|
127
|
+
* The block's verdict is not the whole answer. A present block also carries
|
|
128
|
+
* each instance's own verdict on `instances`, keyed as Terraform prints it
|
|
129
|
+
* (`[0]`, `["a"]`), which the live graph draws as an instance node under the
|
|
130
|
+
* block node (#4454). The state read does the same with the rows it found.
|
|
123
131
|
*
|
|
124
132
|
* ## What is readable at all
|
|
125
133
|
*
|
|
@@ -195,6 +203,31 @@
|
|
|
195
203
|
* The cost is two refreshes of the estate per read, run one after the other
|
|
196
204
|
* so they never share the root's cache file.
|
|
197
205
|
*
|
|
206
|
+
* ## Engine facts on a live root (#4528)
|
|
207
|
+
*
|
|
208
|
+
* After `live-plan -json` answers, the same document is handed to `choudoufu
|
|
209
|
+
* live-graph -json -from-plan=<file>` (choudoufu#2285), which builds the
|
|
210
|
+
* root's graph from the configuration and that file alone: no second live
|
|
211
|
+
* read, so the facts and the verdicts above come from one refresh (choudoufu
|
|
212
|
+
* #1014, the #4520 ruling Q3). `<file>` is the `<root>.live-plan.json`
|
|
213
|
+
* written under {@link TERRAFORM_LIVE_PLAN_DIR_ENV} when the caller asked
|
|
214
|
+
* for it, and otherwise a copy in a temporary directory removed afterwards.
|
|
215
|
+
*
|
|
216
|
+
* The document's node ids are choudoufu's addresses (the ruling's Q2). A
|
|
217
|
+
* block node maps to its entity with {@link entityKeyFor}; an instance node
|
|
218
|
+
* (`instanceOf` set) maps to its block's entity, and its facts go on that
|
|
219
|
+
* block's `instances` entry of the same address, from which core's
|
|
220
|
+
* `observedInstanceNodeId` draws the instance node. Each node's `facts` land
|
|
221
|
+
* on `ResourceMetadata.facts` or `InstanceObservation.facts`, and edges with
|
|
222
|
+
* a grain land on the observation's `edges`, endpoints mapped the same way
|
|
223
|
+
* ({@link readEngineGraph}). Facts are never read for a decision: ownership
|
|
224
|
+
* and the change set keep reading the verdicts above.
|
|
225
|
+
*
|
|
226
|
+
* A choudoufu without the command, older than
|
|
227
|
+
* `MIN_CHOUDOUFU_GRAPH_VERSION`, answers with a usage error: `facts` stay
|
|
228
|
+
* absent, the root gets one note, and the rest of the read is unchanged. Any
|
|
229
|
+
* other failure of the graph read degrades the same way, with its own note.
|
|
230
|
+
*
|
|
198
231
|
* ## Nothing from `values` is surfaced
|
|
199
232
|
*
|
|
200
233
|
* A state row's `values` are the resource's full attribute set, secrets
|
|
@@ -204,16 +237,20 @@
|
|
|
204
237
|
* `id`, which is the physical id every observation carries.
|
|
205
238
|
*/
|
|
206
239
|
import { mergeObservations, normalizeObservation, observation, observeEntities, } from "@intentius/chant/observation";
|
|
207
|
-
import {
|
|
240
|
+
import { observedInstanceNodeId, rollupInstances, terraformInstancePath, TERRAFORM_INSTANCE_ROLLUP, } from "@intentius/chant/instance-nodes";
|
|
241
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
242
|
+
import { tmpdir } from "node:os";
|
|
208
243
|
import { isAbsolute, join } from "node:path";
|
|
209
|
-
import { choudoufuLiveLs, choudoufuLivePlanDocument, terraformInit, terraformPlanRead, terraformShow, TerraformPlanReadError, } from "./op/activities/terraform.js";
|
|
244
|
+
import { choudoufuLiveGraph, choudoufuLiveLs, choudoufuLivePlanDocument, MIN_CHOUDOUFU_GRAPH_VERSION, terraformInit, terraformPlanRead, terraformShow, TerraformPlanReadError, } from "./op/activities/terraform.js";
|
|
210
245
|
import { blockAddressOf, indexPlan, planAttributesFor, plannedAttributesFor } from "./plan-observation.js";
|
|
246
|
+
import { LIVE_PLAN_OMISSION_REASONS, readsAsCredentials } from "./live-plan-reasons.js";
|
|
211
247
|
import { DATA_TYPE, MODULE_TYPE, RESOURCE_TYPE, callersOfKey } from "./hcl/parse.js";
|
|
212
248
|
// The channel keys live in their own module so `plugin.ts` can declare
|
|
213
249
|
// `ownershipChannel` without loading this reader. Re-exported here because
|
|
214
250
|
// this is where they are used.
|
|
215
251
|
export { TERRAFORM_STATE_OWNERSHIP_KEYS } from "./state-ownership.js";
|
|
216
252
|
export { TERRAFORM_LIVE_MARKER_KEYS } from "./live-ownership.js";
|
|
253
|
+
export { LIVE_PLAN_OMISSION_REASONS } from "./live-plan-reasons.js";
|
|
217
254
|
function asRecord(value) {
|
|
218
255
|
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
219
256
|
? value
|
|
@@ -273,12 +310,26 @@ export function indexStateResources(showJson) {
|
|
|
273
310
|
export function classifyStateOwnership(address, index) {
|
|
274
311
|
return index.rows.has(address) ? "owned" : "unknown";
|
|
275
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* True when `instance` is the module call `address` itself or sits beneath it,
|
|
315
|
+
* at any instance key. `address` is a declared module address with no keys
|
|
316
|
+
* (`module.app`, `module.outer.module.inner`); a state or live-plan address
|
|
317
|
+
* carries them (`module.app[0]`, `module.outer["a"].module.inner[1].aws_eip.x`),
|
|
318
|
+
* so the keys come off before the prefix test (#4513).
|
|
319
|
+
*/
|
|
320
|
+
function underModule(instance, address) {
|
|
321
|
+
const block = blockAddressOf(instance);
|
|
322
|
+
return block === address || block.startsWith(`${address}.`);
|
|
323
|
+
}
|
|
276
324
|
/** True when the state carries at least one resource beneath `module.<name>`. */
|
|
277
325
|
function moduleIsLive(address, index) {
|
|
278
|
-
|
|
279
|
-
|
|
326
|
+
// A keyed call's child_modules[] entries are `module.app[0]`, never
|
|
327
|
+
// `module.app`, and so are its rows' prefixes (#4513).
|
|
328
|
+
for (const module of index.modules)
|
|
329
|
+
if (underModule(module, address))
|
|
330
|
+
return true;
|
|
280
331
|
for (const key of index.rows.keys())
|
|
281
|
-
if (key
|
|
332
|
+
if (underModule(key, address))
|
|
282
333
|
return true;
|
|
283
334
|
return false;
|
|
284
335
|
}
|
|
@@ -370,39 +421,6 @@ export function indexLivePlan(document) {
|
|
|
370
421
|
].sort();
|
|
371
422
|
return index;
|
|
372
423
|
}
|
|
373
|
-
/**
|
|
374
|
-
* choudoufu's omission reason codes, mapped onto chant's total vocabulary
|
|
375
|
-
* (`internal/live/projection/result.go`). `"absent"` is not an
|
|
376
|
-
* {@link UnobservedReason}: it is the tri-state's OBSERVED-ABSENT, the one
|
|
377
|
-
* omission that is a claim of knowledge rather than of ignorance.
|
|
378
|
-
*
|
|
379
|
-
* A code this table does not know maps to `read-failed`, which is the safe
|
|
380
|
-
* direction: no NOT-OBSERVED verdict ever becomes a create or a delete.
|
|
381
|
-
*/
|
|
382
|
-
export const LIVE_PLAN_OMISSION_REASONS = {
|
|
383
|
-
// The provider was asked and reported, normally, that nothing is there.
|
|
384
|
-
ABSENT: "absent",
|
|
385
|
-
// The provider errored, or could not be reached in a usable order.
|
|
386
|
-
FAILED: "read-failed",
|
|
387
|
-
PARENT_UNAVAILABLE: "read-failed",
|
|
388
|
-
CYCLE: "read-failed",
|
|
389
|
-
INCOMPLETE_BLOCK: "read-failed",
|
|
390
|
-
LISTED_NOT_IMPORTABLE: "read-failed",
|
|
391
|
-
// Something exists at the identity and does not carry this estate's marker.
|
|
392
|
-
// Normally answered by the `unowned[]` section before this table is read;
|
|
393
|
-
// this entry is what happens if a document ever carries the omission alone.
|
|
394
|
-
UNOWNED: "read-failed",
|
|
395
|
-
// The mode cannot name, list or tag this instance at all: a server-assigned
|
|
396
|
-
// identity with no marker to find it by, a resource with no cloud object to
|
|
397
|
-
// read, or an address another declared instance has taken over.
|
|
398
|
-
NEEDS_DISCOVERY: "unsupported-kind",
|
|
399
|
-
UNREADABLE: "unsupported-kind",
|
|
400
|
-
SUPERSEDED: "unsupported-kind",
|
|
401
|
-
};
|
|
402
|
-
/** Does this text name a credentials or authorization failure rather than any other error? */
|
|
403
|
-
function readsAsCredentials(text) {
|
|
404
|
-
return /\b(no valid credential|credentials?|not authorized|unauthorized|accessdenied|access denied|expiredtoken|invalidclienttokenid|signature)\b/i.test(text);
|
|
405
|
-
}
|
|
406
424
|
/** The chant verdict for one omission: `no-credentials` when its detail says so. */
|
|
407
425
|
function omissionVerdict(row) {
|
|
408
426
|
const mapped = LIVE_PLAN_OMISSION_REASONS[row.reason] ?? "read-failed";
|
|
@@ -416,11 +434,15 @@ function omissionVerdict(row) {
|
|
|
416
434
|
* #2360), which places the same blocks against the same document.
|
|
417
435
|
*/
|
|
418
436
|
export function instancesOf(address, index) {
|
|
419
|
-
|
|
437
|
+
// `blockAddressOf` strips every key, so an instance under an expanded
|
|
438
|
+
// module call (`module.app[0].aws_eip.pool[1]`) is the block's too (#4488).
|
|
439
|
+
return index.addresses.filter((a) => a === address || a.startsWith(`${address}[`) || blockAddressOf(a) === address);
|
|
420
440
|
}
|
|
421
441
|
/** True when the document names any instance under `module.<name>`, at any depth. */
|
|
422
442
|
function liveModuleMembers(address, index) {
|
|
423
|
-
|
|
443
|
+
// Keys stripped first, so a nested call under a keyed one
|
|
444
|
+
// (`module.outer[0].module.inner["a"].…`) is a member too (#4513).
|
|
445
|
+
return index.addresses.filter((a) => underModule(a, address));
|
|
424
446
|
}
|
|
425
447
|
/**
|
|
426
448
|
* Classify one instance address against the document, `unowned[]` first: a
|
|
@@ -459,6 +481,53 @@ export function classifyLiveInstance(address, index) {
|
|
|
459
481
|
}
|
|
460
482
|
return { kind: "absent" };
|
|
461
483
|
}
|
|
484
|
+
/**
|
|
485
|
+
* Where one instance address of the declared block `address` sits: its own
|
|
486
|
+
* key and the expanded module path (`@intentius/chant/instance-nodes`), or
|
|
487
|
+
* undefined when it is the block's unexpanded address or another block's.
|
|
488
|
+
* An instance under an expanded module call carries `scope` (#4488), so the
|
|
489
|
+
* live graph draws it under the same id the declared graph lists.
|
|
490
|
+
*/
|
|
491
|
+
function instanceKeyAndScope(address, instance) {
|
|
492
|
+
if (instance === address || blockAddressOf(instance) !== address)
|
|
493
|
+
return undefined;
|
|
494
|
+
const path = terraformInstancePath(instance);
|
|
495
|
+
if (!path)
|
|
496
|
+
return undefined;
|
|
497
|
+
return { ...(path.key !== undefined ? { key: path.key } : {}), ...(path.scope !== undefined ? { scope: path.scope } : {}) };
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Each instance's own verdict (#4454), keyed as Terraform prints it, for the
|
|
501
|
+
* block's `instances`. An instance under an expanded module call carries its
|
|
502
|
+
* module path as `scope` (#4488) and its own key when the block is expanded too.
|
|
503
|
+
*/
|
|
504
|
+
function liveInstanceObservations(address, instances, verdicts) {
|
|
505
|
+
const out = [];
|
|
506
|
+
instances.forEach((a, i) => {
|
|
507
|
+
const at = instanceKeyAndScope(address, a);
|
|
508
|
+
if (at === undefined)
|
|
509
|
+
return;
|
|
510
|
+
const v = verdicts[i];
|
|
511
|
+
switch (v.kind) {
|
|
512
|
+
case "owned":
|
|
513
|
+
out.push({ ...at, address: a, verdict: "present", ownership: "owned", status: "bound", ...(v.row.identity ? { physicalId: v.row.identity } : {}) });
|
|
514
|
+
break;
|
|
515
|
+
case "foreign":
|
|
516
|
+
out.push({ ...at, address: a, verdict: "present", ownership: "foreign", status: "unowned", ...(v.row.identity ? { physicalId: v.row.identity } : {}) });
|
|
517
|
+
break;
|
|
518
|
+
case "adoptable":
|
|
519
|
+
out.push({ ...at, address: a, verdict: "present", ownership: "unknown", status: "adoptable", ...(v.row.identity ? { physicalId: v.row.identity } : {}) });
|
|
520
|
+
break;
|
|
521
|
+
case "absent":
|
|
522
|
+
out.push({ ...at, address: a, verdict: "absent" });
|
|
523
|
+
break;
|
|
524
|
+
case "unobserved":
|
|
525
|
+
out.push({ ...at, address: a, verdict: "not-observed", reason: v.reason, detail: v.detail });
|
|
526
|
+
break;
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
return out;
|
|
530
|
+
}
|
|
462
531
|
/**
|
|
463
532
|
* The declared block's verdict, aggregated over its instances in the
|
|
464
533
|
* precedence the module doc states: not-observed, then foreign, then
|
|
@@ -473,16 +542,20 @@ function readLiveResource(entity, index, root, queried) {
|
|
|
473
542
|
return { absent: true, queried };
|
|
474
543
|
const verdicts = instances.map((a) => classifyLiveInstance(a, index));
|
|
475
544
|
const attributes = { address, root, estate: index.estate };
|
|
476
|
-
|
|
545
|
+
const expanded = instances.length > 1 || instances[0] !== address;
|
|
546
|
+
if (expanded)
|
|
477
547
|
attributes.instances = instances;
|
|
478
|
-
const
|
|
479
|
-
|
|
480
|
-
|
|
548
|
+
const perInstance = expanded ? liveInstanceObservations(address, instances, verdicts) : [];
|
|
549
|
+
const withInstances = perInstance.length > 0 ? { instances: perInstance } : {};
|
|
550
|
+
const top = rollupInstances(verdicts, TERRAFORM_INSTANCE_ROLLUP);
|
|
551
|
+
if (top?.kind === "unobserved") {
|
|
552
|
+
return { unobserved: { reason: top.reason, detail: top.detail }, queried };
|
|
481
553
|
}
|
|
482
|
-
const foreign =
|
|
483
|
-
if (foreign
|
|
554
|
+
const foreign = top;
|
|
555
|
+
if (foreign?.kind === "foreign") {
|
|
484
556
|
return {
|
|
485
557
|
present: {
|
|
558
|
+
...withInstances,
|
|
486
559
|
type: entity.type,
|
|
487
560
|
physicalId: foreign.row.identity ?? address,
|
|
488
561
|
status: "unowned",
|
|
@@ -496,8 +569,8 @@ function readLiveResource(entity, index, root, queried) {
|
|
|
496
569
|
queried,
|
|
497
570
|
};
|
|
498
571
|
}
|
|
499
|
-
const adoptable =
|
|
500
|
-
if (adoptable
|
|
572
|
+
const adoptable = top;
|
|
573
|
+
if (adoptable?.kind === "adoptable") {
|
|
501
574
|
// `unknown`, not `foreign`: the resource matches the declaration and one
|
|
502
575
|
// tag write claims it. The two values that write carries are the whole
|
|
503
576
|
// adoption proposal #2105 builds its Op on, so they ride the metadata
|
|
@@ -505,6 +578,7 @@ function readLiveResource(entity, index, root, queried) {
|
|
|
505
578
|
// surfaced, because nothing was read off this resource: it carries none.
|
|
506
579
|
return {
|
|
507
580
|
present: {
|
|
581
|
+
...withInstances,
|
|
508
582
|
type: entity.type,
|
|
509
583
|
physicalId: adoptable.row.identity ?? address,
|
|
510
584
|
status: "adoptable",
|
|
@@ -526,13 +600,14 @@ function readLiveResource(entity, index, root, queried) {
|
|
|
526
600
|
queried,
|
|
527
601
|
};
|
|
528
602
|
}
|
|
529
|
-
|
|
530
|
-
if (owned.length === 0)
|
|
603
|
+
if (top?.kind !== "owned")
|
|
531
604
|
return { absent: true, queried };
|
|
605
|
+
const owned = verdicts.filter((v) => v.kind === "owned");
|
|
532
606
|
const sources = [...new Set(owned.map((v) => v.row.source ?? "unknown"))].sort();
|
|
533
607
|
const byMarker = sources.length === 1 && sources[0] === "marker";
|
|
534
608
|
return {
|
|
535
609
|
present: {
|
|
610
|
+
...withInstances,
|
|
536
611
|
type: entity.type,
|
|
537
612
|
physicalId: owned.length === 1 ? (owned[0].row.identity ?? address) : address,
|
|
538
613
|
status: "bound",
|
|
@@ -572,17 +647,23 @@ export const TERRAFORM_LIVE_PLAN_DIR_ENV = "CHANT_TERRAFORM_LIVE_PLAN_DIR";
|
|
|
572
647
|
export function livePlanDocumentFile(root) {
|
|
573
648
|
return `${root.replace(/[^A-Za-z0-9._-]/g, "_")}.live-plan.json`;
|
|
574
649
|
}
|
|
575
|
-
/**
|
|
650
|
+
/**
|
|
651
|
+
* Write a live root's document where {@link TERRAFORM_LIVE_PLAN_DIR_ENV} asks,
|
|
652
|
+
* if it asks. The path written, or undefined when nothing was.
|
|
653
|
+
*/
|
|
576
654
|
function handLivePlanDocument(root, json) {
|
|
577
655
|
const out = process.env[TERRAFORM_LIVE_PLAN_DIR_ENV];
|
|
578
656
|
if (!out || !isAbsolute(out))
|
|
579
|
-
return;
|
|
657
|
+
return undefined;
|
|
580
658
|
try {
|
|
581
659
|
mkdirSync(out, { recursive: true });
|
|
582
|
-
|
|
660
|
+
const file = join(out, livePlanDocumentFile(root));
|
|
661
|
+
writeFileSync(file, JSON.stringify(json));
|
|
662
|
+
return file;
|
|
583
663
|
}
|
|
584
664
|
catch {
|
|
585
665
|
// Best effort: the read's answer does not depend on the copy.
|
|
666
|
+
return undefined;
|
|
586
667
|
}
|
|
587
668
|
}
|
|
588
669
|
/**
|
|
@@ -590,15 +671,20 @@ function handLivePlanDocument(root, json) {
|
|
|
590
671
|
* the document. `terraform show` is never run here, and there is no state
|
|
591
672
|
* file to run it over.
|
|
592
673
|
*/
|
|
593
|
-
function liveAdapter(root, cwd, deps) {
|
|
674
|
+
function liveAdapter(root, cwd, deps, handoff = {}) {
|
|
594
675
|
const where = cwd ? { cwd } : {};
|
|
595
676
|
let dir;
|
|
596
677
|
return {
|
|
597
678
|
async bind() {
|
|
598
679
|
const planned = await deps.livePlan({ root, ...where });
|
|
599
680
|
dir = planned.dir;
|
|
600
|
-
handLivePlanDocument(root, planned.json);
|
|
601
|
-
|
|
681
|
+
const file = handLivePlanDocument(root, planned.json);
|
|
682
|
+
const index = indexLivePlan(planned.json);
|
|
683
|
+
handoff.json = planned.json;
|
|
684
|
+
handoff.estate = planned.estate ?? index.estate;
|
|
685
|
+
if (file)
|
|
686
|
+
handoff.file = file;
|
|
687
|
+
return index;
|
|
602
688
|
},
|
|
603
689
|
classifyBindFailure(err) {
|
|
604
690
|
const message = err instanceof Error ? err.message.split("\n")[0] : String(err);
|
|
@@ -651,6 +737,189 @@ function liveAdapter(root, cwd, deps) {
|
|
|
651
737
|
},
|
|
652
738
|
};
|
|
653
739
|
}
|
|
740
|
+
const GRAINS = new Set(["block", "instance", "property"]);
|
|
741
|
+
const OWNERSHIPS = new Set(["bound", "unowned", "pending", "foreign"]);
|
|
742
|
+
const OWNED_BY = new Set(["marker", "record", "name"]);
|
|
743
|
+
/**
|
|
744
|
+
* One node's `facts`, keeping only the fields of chant's `EngineFacts` and
|
|
745
|
+
* only values of the shape it declares. Undefined when nothing is left.
|
|
746
|
+
*/
|
|
747
|
+
function engineFactsOf(value) {
|
|
748
|
+
const f = asRecord(value);
|
|
749
|
+
const out = {};
|
|
750
|
+
const ownership = asString(f.ownership);
|
|
751
|
+
if (ownership && OWNERSHIPS.has(ownership))
|
|
752
|
+
out.ownership = ownership;
|
|
753
|
+
const ownedBy = asString(f.ownedBy);
|
|
754
|
+
if (ownedBy && OWNED_BY.has(ownedBy))
|
|
755
|
+
out.ownedBy = ownedBy;
|
|
756
|
+
const markers = asRecord(f.markers);
|
|
757
|
+
const encoding = asString(markers.encoding);
|
|
758
|
+
const source = asString(markers.source);
|
|
759
|
+
if ((encoding === "plain" || encoding === "escaped" || encoding === "digest") && (source === "live" || source === "record")) {
|
|
760
|
+
out.markers = {
|
|
761
|
+
...(asString(markers.owner) ? { owner: asString(markers.owner) } : {}),
|
|
762
|
+
...(asString(markers.address) ? { address: asString(markers.address) } : {}),
|
|
763
|
+
encoding,
|
|
764
|
+
source,
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
const cloudIds = asArray(f.cloudIds)
|
|
768
|
+
.map((c) => ({ kind: asString(asRecord(c).kind), value: asString(asRecord(c).value) }))
|
|
769
|
+
.filter((c) => c.value !== undefined && ["import-id", "arn", "provider-id", "self-link", "k8s-uid"].includes(c.kind ?? ""));
|
|
770
|
+
if (cloudIds.length > 0)
|
|
771
|
+
out.cloudIds = cloudIds;
|
|
772
|
+
const history = asRecord(f.recordVersions);
|
|
773
|
+
if (typeof history.kept === "boolean") {
|
|
774
|
+
out.recordVersions = {
|
|
775
|
+
kept: history.kept,
|
|
776
|
+
versions: asArray(history.versions).flatMap((v) => {
|
|
777
|
+
const r = asRecord(v);
|
|
778
|
+
const id = asString(r.id);
|
|
779
|
+
const writtenAt = asString(r.writtenAt);
|
|
780
|
+
return id && writtenAt ? [{ id, writtenAt, current: r.current === true, deleted: r.deleted === true }] : [];
|
|
781
|
+
}),
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
const observedAt = asString(f.observedAt);
|
|
785
|
+
if (observedAt)
|
|
786
|
+
out.observedAt = observedAt;
|
|
787
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Read an engine graph document (`choudoufu live-graph -json`, chant#4527's
|
|
791
|
+
* schema) for one root into chant's id space. Node ids are choudoufu's
|
|
792
|
+
* addresses (the #4520 ruling, Q2): a block node is the entity
|
|
793
|
+
* {@link entityKeyFor} names; an instance node (`instanceOf`) belongs to its
|
|
794
|
+
* block's entity, and as an edge endpoint it is the live instance node id
|
|
795
|
+
* core's `observedInstanceNodeId` gives. A node with no address (an estate
|
|
796
|
+
* the configuration reads, `estate:<name>`) has no chant entity, so its
|
|
797
|
+
* edges are left out. Edges keep their grain; one without a grain is left out.
|
|
798
|
+
*
|
|
799
|
+
* Throws when the document is not an engine graph document.
|
|
800
|
+
*/
|
|
801
|
+
export function readEngineGraph(root, document) {
|
|
802
|
+
const doc = asRecord(document);
|
|
803
|
+
const engineGraph = asRecord(asRecord(doc.meta).engineGraph);
|
|
804
|
+
if (doc.version !== 1 || engineGraph.format !== 1 || !Array.isArray(doc.nodes)) {
|
|
805
|
+
throw new Error("not an engine graph document (want GraphIR version 1 with meta.engineGraph format 1)");
|
|
806
|
+
}
|
|
807
|
+
const blocks = new Map();
|
|
808
|
+
const instances = new Map();
|
|
809
|
+
const nodeIds = new Map();
|
|
810
|
+
for (const entry of doc.nodes) {
|
|
811
|
+
const node = asRecord(entry);
|
|
812
|
+
const id = asString(node.id);
|
|
813
|
+
const address = asString(asRecord(node.attrs).address);
|
|
814
|
+
if (!id || !address)
|
|
815
|
+
continue;
|
|
816
|
+
const facts = engineFactsOf(node.facts);
|
|
817
|
+
const instanceOf = asString(node.instanceOf);
|
|
818
|
+
if (instanceOf) {
|
|
819
|
+
const block = entityKeyFor(root, instanceOf);
|
|
820
|
+
const key = asString(node.instanceKey);
|
|
821
|
+
const scope = asString(node.instanceScope);
|
|
822
|
+
const liveId = observedInstanceNodeId(block, {
|
|
823
|
+
address: id,
|
|
824
|
+
...(key !== undefined ? { key } : {}),
|
|
825
|
+
...(scope !== undefined ? { scope } : {}),
|
|
826
|
+
});
|
|
827
|
+
if (liveId)
|
|
828
|
+
nodeIds.set(id, liveId);
|
|
829
|
+
if (facts) {
|
|
830
|
+
let byAddress = instances.get(block);
|
|
831
|
+
if (!byAddress)
|
|
832
|
+
instances.set(block, (byAddress = new Map()));
|
|
833
|
+
byAddress.set(id, facts);
|
|
834
|
+
}
|
|
835
|
+
continue;
|
|
836
|
+
}
|
|
837
|
+
const key = entityKeyFor(root, id);
|
|
838
|
+
nodeIds.set(id, key);
|
|
839
|
+
if (facts)
|
|
840
|
+
blocks.set(key, facts);
|
|
841
|
+
}
|
|
842
|
+
const edges = [];
|
|
843
|
+
const seen = new Set();
|
|
844
|
+
for (const entry of asArray(doc.edges)) {
|
|
845
|
+
const edge = asRecord(entry);
|
|
846
|
+
const grain = asString(edge.grain);
|
|
847
|
+
if (!grain || !GRAINS.has(grain))
|
|
848
|
+
continue;
|
|
849
|
+
const from = nodeIds.get(asString(edge.from) ?? "");
|
|
850
|
+
const to = nodeIds.get(asString(edge.to) ?? "");
|
|
851
|
+
if (!from || !to || from === to)
|
|
852
|
+
continue;
|
|
853
|
+
const viaAttr = asString(edge.viaAttr);
|
|
854
|
+
const key = `${from}\0${to}\0${viaAttr ?? ""}\0${grain}`;
|
|
855
|
+
if (seen.has(key))
|
|
856
|
+
continue;
|
|
857
|
+
seen.add(key);
|
|
858
|
+
edges.push({ from, to, kind: "ref", ...(viaAttr ? { viaAttr } : {}), grain: grain });
|
|
859
|
+
}
|
|
860
|
+
return { blocks, instances, edges };
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* `resources` with {@link readEngineGraph}'s facts on them: a block's on
|
|
864
|
+
* `ResourceMetadata.facts`, an instance's on its `instances` entry of the
|
|
865
|
+
* same address. Nothing else changes, and nothing is added for an entity the
|
|
866
|
+
* read did not return.
|
|
867
|
+
*/
|
|
868
|
+
export function withEngineFacts(resources, read) {
|
|
869
|
+
const out = {};
|
|
870
|
+
for (const [name, meta] of Object.entries(resources)) {
|
|
871
|
+
const facts = read.blocks.get(name);
|
|
872
|
+
const byAddress = read.instances.get(name);
|
|
873
|
+
const instances = byAddress && meta.instances
|
|
874
|
+
? meta.instances.map((inst) => {
|
|
875
|
+
const f = byAddress.get(inst.address);
|
|
876
|
+
return f ? { ...inst, facts: f } : inst;
|
|
877
|
+
})
|
|
878
|
+
: meta.instances;
|
|
879
|
+
out[name] = {
|
|
880
|
+
...meta,
|
|
881
|
+
...(facts ? { facts } : {}),
|
|
882
|
+
...(instances ? { instances } : {}),
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
return out;
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Run `choudoufu live-graph -json -from-plan=<file>` over the document a
|
|
889
|
+
* live root's bind handed off, and read it (#4528). Never throws: facts are
|
|
890
|
+
* extra, so a failure is a note and no facts.
|
|
891
|
+
*/
|
|
892
|
+
async function engineGraphFor(root, cwd, deps, handoff) {
|
|
893
|
+
if (!deps.liveGraph || handoff.json === undefined)
|
|
894
|
+
return {};
|
|
895
|
+
let scratch;
|
|
896
|
+
try {
|
|
897
|
+
let file = handoff.file;
|
|
898
|
+
if (!file) {
|
|
899
|
+
scratch = mkdtempSync(join(tmpdir(), "chant-live-graph-"));
|
|
900
|
+
file = join(scratch, livePlanDocumentFile(root));
|
|
901
|
+
writeFileSync(file, JSON.stringify(handoff.json));
|
|
902
|
+
}
|
|
903
|
+
const graph = await deps.liveGraph({ root, ...(cwd ? { cwd } : {}), fromPlan: file, ...(handoff.estate ? { estate: handoff.estate } : {}) });
|
|
904
|
+
if (!graph.supported) {
|
|
905
|
+
return {
|
|
906
|
+
note: `terraform.roots.${root}: engine facts are absent: this choudoufu has no \`live-graph -from-plan\` ` +
|
|
907
|
+
`(${graph.detail}), which needs v${MIN_CHOUDOUFU_GRAPH_VERSION} or later; the rest of the read is unchanged`,
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
return { read: readEngineGraph(root, graph.json) };
|
|
911
|
+
}
|
|
912
|
+
catch (err) {
|
|
913
|
+
const message = (err instanceof Error ? err.message : String(err)).split("\n")[0];
|
|
914
|
+
return {
|
|
915
|
+
note: `terraform.roots.${root}: engine facts are absent: \`choudoufu live-graph -json -from-plan\` failed (${message}); the rest of the read is unchanged`,
|
|
916
|
+
};
|
|
917
|
+
}
|
|
918
|
+
finally {
|
|
919
|
+
if (scratch)
|
|
920
|
+
rmSync(scratch, { recursive: true, force: true });
|
|
921
|
+
}
|
|
922
|
+
}
|
|
654
923
|
/** Parse a `live-ls -json` document. A missing section reads as empty, never as a throw. */
|
|
655
924
|
export function readLiveLs(document) {
|
|
656
925
|
const doc = asRecord(document);
|
|
@@ -731,7 +1000,8 @@ export function ambientKinds() {
|
|
|
731
1000
|
return [RESOURCE_TYPE];
|
|
732
1001
|
}
|
|
733
1002
|
/**
|
|
734
|
-
* Every live root the project declares, in config order
|
|
1003
|
+
* Every live root the project declares, in config order, leaving out a
|
|
1004
|
+
* `signalOnly` one (#4484). Reads the project
|
|
735
1005
|
* config the same way the activities do, so `terraform.roots` is read once
|
|
736
1006
|
* and the same answer reaches both.
|
|
737
1007
|
*/
|
|
@@ -748,6 +1018,9 @@ export async function liveRootNames(cwd) {
|
|
|
748
1018
|
return [];
|
|
749
1019
|
const live = [];
|
|
750
1020
|
for (const [name, root] of Object.entries(namespace.roots ?? {})) {
|
|
1021
|
+
// A `signalOnly` root (#4484) is another project's: it only brings this one into a change.
|
|
1022
|
+
if (root.signalOnly === true)
|
|
1023
|
+
continue;
|
|
751
1024
|
const estate = detectLiveEstate(resolve(projectRoot, root.dir));
|
|
752
1025
|
if (estate !== undefined)
|
|
753
1026
|
live.push({ root: name, estate });
|
|
@@ -875,6 +1148,7 @@ const REAL_DEPS = {
|
|
|
875
1148
|
show: terraformShow,
|
|
876
1149
|
livePlan: choudoufuLivePlanDocument,
|
|
877
1150
|
liveLs: choudoufuLiveLs,
|
|
1151
|
+
liveGraph: choudoufuLiveGraph,
|
|
878
1152
|
planRead: terraformPlanRead,
|
|
879
1153
|
};
|
|
880
1154
|
/**
|
|
@@ -965,6 +1239,22 @@ function blockRows(address, index) {
|
|
|
965
1239
|
return [exact];
|
|
966
1240
|
return [...index.rows.values()].filter((row) => blockAddressOf(row.address) === address);
|
|
967
1241
|
}
|
|
1242
|
+
/**
|
|
1243
|
+
* Each row of an expanded block as an instance (#4454), keyed as Terraform
|
|
1244
|
+
* prints it. A state row is a recorded instance, owned by membership. A row
|
|
1245
|
+
* under an expanded module call carries its module path as `scope`, as on
|
|
1246
|
+
* the live read (#4488).
|
|
1247
|
+
*/
|
|
1248
|
+
function stateInstanceObservations(address, rows) {
|
|
1249
|
+
const out = [];
|
|
1250
|
+
for (const r of rows) {
|
|
1251
|
+
const at = instanceKeyAndScope(address, r.address);
|
|
1252
|
+
if (at === undefined)
|
|
1253
|
+
continue;
|
|
1254
|
+
out.push({ ...at, address: r.address, verdict: "present", ownership: "owned", status: r.mode ?? "managed", ...(r.id ? { physicalId: r.id } : {}) });
|
|
1255
|
+
}
|
|
1256
|
+
return out.sort((a, b) => a.address.localeCompare(b.address));
|
|
1257
|
+
}
|
|
968
1258
|
/**
|
|
969
1259
|
* One declared entity against a state index: the state read's whole verdict,
|
|
970
1260
|
* and the plan depth's too, since a plan's `prior_state` is the same shape.
|
|
@@ -973,14 +1263,18 @@ function blockRows(address, index) {
|
|
|
973
1263
|
function readStateEntity(index, entity, root, queried, extra) {
|
|
974
1264
|
const { address } = entity;
|
|
975
1265
|
if (entity.type === RESOURCE_TYPE || entity.type === DATA_TYPE) {
|
|
976
|
-
// The exact row first, which is the state read's rule since #2087
|
|
977
|
-
//
|
|
978
|
-
|
|
1266
|
+
// The exact row first, which is the state read's rule since #2087, then
|
|
1267
|
+
// a `count` or `for_each` block by its instances: the plan depth did
|
|
1268
|
+
// that from the start, and the state read does since #4454, which is
|
|
1269
|
+
// what gives a drift row for `aws_eip.pool[0]` a block to roll up to.
|
|
1270
|
+
const rows = blockRows(address, index);
|
|
979
1271
|
if (rows.length === 0)
|
|
980
1272
|
return { absent: true, queried };
|
|
981
1273
|
const row = rows[0];
|
|
1274
|
+
const instances = stateInstanceObservations(address, rows);
|
|
982
1275
|
return {
|
|
983
1276
|
present: {
|
|
1277
|
+
...(instances.length > 0 ? { instances } : {}),
|
|
984
1278
|
type: entity.type,
|
|
985
1279
|
physicalId: rows.length === 1 ? (row.id ?? address) : address,
|
|
986
1280
|
status: row.mode ?? "managed",
|
|
@@ -1125,9 +1419,9 @@ function planAdapter(root, cwd, deps, outcome) {
|
|
|
1125
1419
|
* read, unchanged, with the plan's attributes added to every block it bound.
|
|
1126
1420
|
* See "On a live root" in the module doc.
|
|
1127
1421
|
*/
|
|
1128
|
-
function livePlanDepthAdapter(root, cwd, deps, outcome) {
|
|
1422
|
+
function livePlanDepthAdapter(root, cwd, deps, outcome, handoff = {}) {
|
|
1129
1423
|
const where = cwd ? { cwd } : {};
|
|
1130
|
-
const live = liveAdapter(root, cwd, deps);
|
|
1424
|
+
const live = liveAdapter(root, cwd, deps, handoff);
|
|
1131
1425
|
const planRead = deps.planRead ?? terraformPlanRead;
|
|
1132
1426
|
const firstLine = (err) => (err instanceof Error ? err.message : String(err)).split("\n")[0];
|
|
1133
1427
|
let command = "";
|
|
@@ -1241,6 +1535,17 @@ export async function describeResources(options, deps = REAL_DEPS) {
|
|
|
1241
1535
|
// an overlay exists to prevent.
|
|
1242
1536
|
const sources = {};
|
|
1243
1537
|
const rootReads = {};
|
|
1538
|
+
const edges = [];
|
|
1539
|
+
// A live root's observation with the engine graph's facts and edges on it (#4528).
|
|
1540
|
+
const withEngineGraph = async (root, handoff, observed) => {
|
|
1541
|
+
const graph = await engineGraphFor(root, options.cwd, deps, handoff);
|
|
1542
|
+
if (graph.note)
|
|
1543
|
+
notes.push(graph.note);
|
|
1544
|
+
if (!graph.read)
|
|
1545
|
+
return observed;
|
|
1546
|
+
edges.push(...graph.read.edges);
|
|
1547
|
+
return { ...observed, resources: withEngineFacts(observed.resources, graph.read) };
|
|
1548
|
+
};
|
|
1244
1549
|
const depthOf = byRoot.size > 0 ? await observeDepths(options, notes) : () => "state";
|
|
1245
1550
|
for (const [root, declared] of byRoot) {
|
|
1246
1551
|
// One fact decides the whole read, and the parse already recorded it on
|
|
@@ -1255,19 +1560,22 @@ export async function describeResources(options, deps = REAL_DEPS) {
|
|
|
1255
1560
|
// Both reads (#4371): `live-plan` for ownership, the plan for the
|
|
1256
1561
|
// attributes on what it bound. `sources` is known only after the read.
|
|
1257
1562
|
const outcome = { answered: "live", note: "" };
|
|
1258
|
-
const
|
|
1563
|
+
const handoff = {};
|
|
1564
|
+
const read = await observeEntities(declared, livePlanDepthAdapter(root, options.cwd, deps, outcome, handoff));
|
|
1259
1565
|
for (const entity of declared)
|
|
1260
1566
|
sources[entity.name] = outcome.answered;
|
|
1261
1567
|
if (outcome.read)
|
|
1262
1568
|
rootReads[`terraform.roots.${root}`] = outcome.read;
|
|
1263
1569
|
if (outcome.note)
|
|
1264
1570
|
notes.push(outcome.note);
|
|
1265
|
-
parts.push(normalizeObservation(read));
|
|
1571
|
+
parts.push(await withEngineGraph(root, handoff, normalizeObservation(read)));
|
|
1266
1572
|
continue;
|
|
1267
1573
|
}
|
|
1268
1574
|
for (const entity of declared)
|
|
1269
1575
|
sources[entity.name] = "live";
|
|
1270
|
-
|
|
1576
|
+
const handoff = {};
|
|
1577
|
+
const read = await observeEntities(declared, liveAdapter(root, options.cwd, deps, handoff));
|
|
1578
|
+
parts.push(await withEngineGraph(root, handoff, normalizeObservation(read)));
|
|
1271
1579
|
continue;
|
|
1272
1580
|
}
|
|
1273
1581
|
if (depth === "plan") {
|
|
@@ -1319,5 +1627,5 @@ export async function describeResources(options, deps = REAL_DEPS) {
|
|
|
1319
1627
|
}
|
|
1320
1628
|
// A planned create's plan attributes (#4372) ride beside the verdict, never
|
|
1321
1629
|
// in `resources`: the block stays absent.
|
|
1322
|
-
return observation(resources, unobserved, merged.queried, merged.notes, undefined, sources, merged.annotations, rootReads);
|
|
1630
|
+
return observation(resources, unobserved, merged.queried, merged.notes, undefined, sources, merged.annotations, rootReads, edges);
|
|
1323
1631
|
}
|