@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
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The plan shape of a terraform-family root (#4436): what `terraform show
|
|
3
|
+
* -json` says a plan does, without the values, in the form core's
|
|
4
|
+
* `coveredRound` compares (#4419). `terraform-apply`'s `plan` returns it, and
|
|
5
|
+
* terragucci calls it for the plan JSON of a note (terragucci#1268).
|
|
6
|
+
*
|
|
7
|
+
* Like `./change-set`, this module imports only `@intentius/chant` subpaths,
|
|
8
|
+
* never the lexicon's entry point.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { PlanShape, PlanShapeEntry, ShapeReplacement } from "@intentius/chant/components/covered-round";
|
|
12
|
+
import { normalizePlanShape } from "@intentius/chant/components/covered-round";
|
|
13
|
+
import { actionFor } from "./change-set";
|
|
14
|
+
|
|
15
|
+
type Json = Record<string, unknown>;
|
|
16
|
+
|
|
17
|
+
const isObject = (v: unknown): v is Json => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
18
|
+
|
|
19
|
+
/** Whether an `after_unknown` value marks anything under it unknown. */
|
|
20
|
+
function marks(v: unknown): boolean {
|
|
21
|
+
if (v === true) return true;
|
|
22
|
+
if (Array.isArray(v)) return v.some(marks);
|
|
23
|
+
if (isObject(v)) return Object.values(v).some(marks);
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function sameJson(a: unknown, b: unknown): boolean {
|
|
28
|
+
if (a === b) return true;
|
|
29
|
+
if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((x, i) => sameJson(x, b[i]));
|
|
30
|
+
if (isObject(a) && isObject(b)) {
|
|
31
|
+
const ka = Object.keys(a);
|
|
32
|
+
return ka.length === Object.keys(b).length && ka.every((k) => k in b && sameJson(a[k], b[k]));
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Whether the value at `path` in an `after_unknown` tree is unknown: `true` at the path or on a prefix of it. */
|
|
38
|
+
function unknownAt(tree: unknown, path: unknown[]): boolean {
|
|
39
|
+
let at: unknown = tree;
|
|
40
|
+
for (const step of path) {
|
|
41
|
+
if (at === true) return true;
|
|
42
|
+
if (Array.isArray(at) && typeof step === "number") at = at[step];
|
|
43
|
+
else if (isObject(at) && typeof step === "string") at = at[step];
|
|
44
|
+
else return false;
|
|
45
|
+
}
|
|
46
|
+
return marks(at);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* How a change replaces its resource. A `replace_paths` entry names an
|
|
51
|
+
* attribute whose change forces it. When every such attribute is unknown
|
|
52
|
+
* after apply, the plan cannot say the value will differ, so the replacement
|
|
53
|
+
* is `conditional`; one with a known forcing attribute is `true`. A delete
|
|
54
|
+
* and create pair with no `replace_paths` (a tainted object, `-replace`) is
|
|
55
|
+
* `true`. An update with none replaces nothing (`false`); a create or delete
|
|
56
|
+
* has no replacement to state.
|
|
57
|
+
*/
|
|
58
|
+
function replacementFor(change: Json, action: string): ShapeReplacement | undefined {
|
|
59
|
+
const paths = (Array.isArray(change.replace_paths) ? change.replace_paths : []).filter(Array.isArray) as unknown[][];
|
|
60
|
+
if (paths.length > 0) return paths.every((p) => unknownAt(change.after_unknown, p)) ? "conditional" : "true";
|
|
61
|
+
if (action === "replace") return "true";
|
|
62
|
+
if (action === "update") return "false";
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface TerraformPlanShapeOptions {
|
|
67
|
+
/** The inputs the plan was made without, as `<component>.<output>`. */
|
|
68
|
+
unknownInputs?: string[];
|
|
69
|
+
/** The inputs the plan read with a value, by reference. */
|
|
70
|
+
knownInputs?: Record<string, unknown>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* The shape of `planJson` (`terraform show -json`, from terraform, tofu or
|
|
75
|
+
* choudoufu) for `member`.
|
|
76
|
+
*
|
|
77
|
+
* One entry per `resource_changes` item that is not `no-op` or `read`.
|
|
78
|
+
* `logicalId` is the address, with `#<deposed>` for a deposed object. `type`
|
|
79
|
+
* is the resource type. `properties` are the top-level attributes that differ
|
|
80
|
+
* between `before` and `after` (on a create, those the plan sets or leaves
|
|
81
|
+
* unknown), and `unknown` the ones `after_unknown` marks, so `unknown` is
|
|
82
|
+
* within `properties`. A delete has no properties. Values never enter it, so
|
|
83
|
+
* a sensitive attribute is only a name.
|
|
84
|
+
*/
|
|
85
|
+
export function terraformPlanShape(planJson: unknown, member: string, options: TerraformPlanShapeOptions = {}): PlanShape {
|
|
86
|
+
const plan = isObject(planJson) ? planJson : {};
|
|
87
|
+
const raw = Array.isArray(plan.resource_changes) ? plan.resource_changes : [];
|
|
88
|
+
const entries: PlanShapeEntry[] = [];
|
|
89
|
+
for (const r of raw) {
|
|
90
|
+
const rc = isObject(r) ? r : {};
|
|
91
|
+
const change = isObject(rc.change) ? rc.change : {};
|
|
92
|
+
const action = actionFor(change.actions);
|
|
93
|
+
if (action === "no-op" || action === "read") continue;
|
|
94
|
+
const address = String(rc.address ?? "");
|
|
95
|
+
const before = isObject(change.before) ? change.before : {};
|
|
96
|
+
const after = isObject(change.after) ? change.after : {};
|
|
97
|
+
const afterUnknown = isObject(change.after_unknown) ? change.after_unknown : {};
|
|
98
|
+
const properties: string[] = [];
|
|
99
|
+
const unknown: string[] = [];
|
|
100
|
+
if (action !== "delete" && action !== "forget") {
|
|
101
|
+
for (const k of new Set([...Object.keys(before), ...Object.keys(after), ...Object.keys(afterUnknown)])) {
|
|
102
|
+
const isUnknown = marks(afterUnknown[k]);
|
|
103
|
+
const differs =
|
|
104
|
+
action === "create"
|
|
105
|
+
? isUnknown || (after[k] !== undefined && after[k] !== null)
|
|
106
|
+
: isUnknown || !sameJson(before[k] ?? null, after[k] ?? null);
|
|
107
|
+
if (!differs) continue;
|
|
108
|
+
properties.push(k);
|
|
109
|
+
if (isUnknown) unknown.push(k);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const replacement = replacementFor(change, action);
|
|
113
|
+
entries.push({
|
|
114
|
+
logicalId: typeof rc.deposed === "string" ? `${address}#${rc.deposed}` : address,
|
|
115
|
+
action,
|
|
116
|
+
...(replacement ? { replacement } : {}),
|
|
117
|
+
...(typeof rc.type === "string" ? { type: rc.type } : {}),
|
|
118
|
+
properties,
|
|
119
|
+
unknown,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return normalizePlanShape({
|
|
123
|
+
member,
|
|
124
|
+
entries,
|
|
125
|
+
unknownInputs: options.unknownInputs ?? [],
|
|
126
|
+
...(options.knownInputs ? { knownInputs: options.knownInputs } : {}),
|
|
127
|
+
});
|
|
128
|
+
}
|
package/src/plugin.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { lastMemberReport, readPulumiMember, setLastMemberReport } from "./workspace-member";
|
|
2
1
|
import type { AuditEntitiesInput, LexiconPlugin } from "@intentius/chant/lexicon";
|
|
2
|
+
import { terraformCiSetup } from "./ci-setup";
|
|
3
3
|
import { terraformBehaviourKinds } from "./behaviour/kinds";
|
|
4
4
|
import type { CompletionContext, HoverContext } from "@intentius/chant/lsp/types";
|
|
5
5
|
import type { Declarable } from "@intentius/chant/declarable";
|
|
@@ -11,7 +11,7 @@ import { withCallersChain } from "./lint/post-synth/scope";
|
|
|
11
11
|
import { terraformAuditCatalog } from "./lint/audit-catalog";
|
|
12
12
|
import { completions } from "./lsp/completions";
|
|
13
13
|
import { hover } from "./lsp/hover";
|
|
14
|
-
import { terraformConfigSchema, type TerraformConfig } from "./config";
|
|
14
|
+
import { ownRoots, terraformConfigSchema, type TerraformConfig } from "./config";
|
|
15
15
|
import { renderTerraformRoots } from "./hcl/roots";
|
|
16
16
|
import { existsSync } from "node:fs";
|
|
17
17
|
import { join } from "node:path";
|
|
@@ -20,6 +20,7 @@ import { descendModules } from "./hcl/descend";
|
|
|
20
20
|
import { TERRAFORM_STATE_OWNERSHIP_KEYS } from "./state-ownership";
|
|
21
21
|
import { terraformCommands } from "./commands";
|
|
22
22
|
import { terraformCapabilityPack } from "./capabilities/adapter";
|
|
23
|
+
import { TERRAFORM_REFERENCE_CATALOG } from "./behaviour/reference-catalog";
|
|
23
24
|
|
|
24
25
|
const loadSkills = createSkillsLoader(import.meta.url, [
|
|
25
26
|
{
|
|
@@ -79,9 +80,16 @@ export const terraformPlugin: LexiconPlugin = {
|
|
|
79
80
|
behaviourKinds: terraformBehaviourKinds,
|
|
80
81
|
name: "terraform",
|
|
81
82
|
capabilityPack: terraformCapabilityPack,
|
|
83
|
+
// Keyed by provider type (#2360); see its module doc for which nodes it reads (#4535).
|
|
84
|
+
referenceCatalog: TERRAFORM_REFERENCE_CATALOG,
|
|
82
85
|
serializer: terraformSerializer,
|
|
83
86
|
configSchema: terraformConfigSchema,
|
|
84
87
|
|
|
88
|
+
// #4550: the engine install lines for the pull request pipeline's default image.
|
|
89
|
+
ciSetup(ctx: { dir: string }): string[] {
|
|
90
|
+
return terraformCiSetup(ctx);
|
|
91
|
+
},
|
|
92
|
+
|
|
85
93
|
// ── Required lifecycle methods ────────────────────────────────
|
|
86
94
|
|
|
87
95
|
async generate(options?: { verbose?: boolean }): Promise<void> {
|
|
@@ -141,6 +149,18 @@ export const terraformPlugin: LexiconPlugin = {
|
|
|
141
149
|
return describeResources(options);
|
|
142
150
|
},
|
|
143
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Each root's drift, as drift-record stream lines (behold#995): a stock
|
|
154
|
+
* root through its state or a plan, a live root through `live-plan` (and a
|
|
155
|
+
* plan), one resource through `live-plan -resource`. `chant workspace
|
|
156
|
+
* drift` reaches it through `chant lifecycle drift` in a member's reader
|
|
157
|
+
* project. See `./drift-read.ts`.
|
|
158
|
+
*/
|
|
159
|
+
async readDrift(options) {
|
|
160
|
+
const { readTerraformDrift } = await import("./drift-read");
|
|
161
|
+
return readTerraformDrift(options);
|
|
162
|
+
},
|
|
163
|
+
|
|
144
164
|
/**
|
|
145
165
|
* The prediction, for whichever estate `options.from` names (#2495). The
|
|
146
166
|
* producer is `predictTerraformBehaviour` and this is its second caller, not
|
|
@@ -181,15 +201,9 @@ export const terraformPlugin: LexiconPlugin = {
|
|
|
181
201
|
* project root, which is what relative `dir` paths resolve against.
|
|
182
202
|
*/
|
|
183
203
|
async buildRoots(ctx): Promise<{ entities: Map<string, Declarable>; warnings: string[] }> {
|
|
184
|
-
setLastMemberReport(undefined);
|
|
185
204
|
const namespace = (ctx.config as { terraform?: TerraformConfig }).terraform;
|
|
186
|
-
// A
|
|
187
|
-
|
|
188
|
-
const read = readPulumiMember({ member: namespace.pulumiMember });
|
|
189
|
-
setLastMemberReport(read.report);
|
|
190
|
-
return { entities: read.entities, warnings: read.warnings };
|
|
191
|
-
}
|
|
192
|
-
const roots = namespace?.roots ?? {};
|
|
205
|
+
// A `signalOnly` root (#4484) feeds change detection only, so it builds no entities here.
|
|
206
|
+
const roots = ownRoots(namespace?.roots);
|
|
193
207
|
if (Object.keys(roots).length === 0) return { entities: new Map(), warnings: [] };
|
|
194
208
|
return renderTerraformRoots({
|
|
195
209
|
projectRoot: ctx.projectRoot,
|
|
@@ -200,11 +214,6 @@ export const terraformPlugin: LexiconPlugin = {
|
|
|
200
214
|
});
|
|
201
215
|
},
|
|
202
216
|
|
|
203
|
-
graphMeta() {
|
|
204
|
-
const report = lastMemberReport();
|
|
205
|
-
return report ? { pulumiMember: report } : undefined;
|
|
206
|
-
},
|
|
207
|
-
|
|
208
217
|
/** `chant terraform pin-rollout` (#3189). */
|
|
209
218
|
commands() {
|
|
210
219
|
return terraformCommands;
|
|
@@ -213,13 +222,15 @@ export const terraformPlugin: LexiconPlugin = {
|
|
|
213
222
|
/**
|
|
214
223
|
* The `terraform.roots` a change touched (#3183): a changed file in the
|
|
215
224
|
* root's directory, in a local module it calls, or one of its var files.
|
|
216
|
-
* See `./changed-roots.ts`.
|
|
225
|
+
* See `./changed-roots.ts`. Every root counts, a `signalOnly` one too
|
|
226
|
+
* (#4484): that is what it is declared for.
|
|
217
227
|
*/
|
|
218
228
|
async changedUnits(ctx) {
|
|
219
|
-
const
|
|
229
|
+
const tf = (ctx.config as { terraform?: TerraformConfig }).terraform;
|
|
230
|
+
const roots = tf?.roots ?? {};
|
|
220
231
|
if (Object.keys(roots).length === 0) return [];
|
|
221
232
|
const { changedRoots } = await import("./changed-roots");
|
|
222
|
-
return changedRoots(ctx.projectRoot, roots, ctx.changedFiles);
|
|
233
|
+
return changedRoots(ctx.projectRoot, roots, ctx.changedFiles, tf?.binary);
|
|
223
234
|
},
|
|
224
235
|
|
|
225
236
|
lintRules() {
|
|
@@ -294,12 +305,21 @@ export const terraformPlugin: LexiconPlugin = {
|
|
|
294
305
|
// A local audit knows the root's directory, so it can say whether the
|
|
295
306
|
// lock file is beside the `.tf` files (TF040); a fetched one cannot.
|
|
296
307
|
const lockFile = input?.dir !== undefined ? existsSync(join(input.dir, LOCK_FILENAME)) : undefined;
|
|
297
|
-
|
|
308
|
+
// An audit has no `terraform.binary` to follow (chant#4457). A root
|
|
309
|
+
// that carries a `.tofu` file is written for OpenTofu, so it is read
|
|
310
|
+
// as a tofu root; any other is read as terraform, the config default.
|
|
311
|
+
const binary = /^# file: .*\.tofu(\.json)?\s*$/m.test(content) ? "tofu" : undefined;
|
|
312
|
+
const modeOptions = {
|
|
313
|
+
...(binary !== undefined ? { binary } : {}),
|
|
314
|
+
...(lockFile !== undefined ? { lockFile } : {}),
|
|
315
|
+
};
|
|
316
|
+
const entities = await parseTerraformRootContent(content, root, undefined, Object.keys(modeOptions).length > 0 ? modeOptions : undefined);
|
|
298
317
|
if (input?.dir === undefined) return entities;
|
|
299
318
|
const { entities: children } = await descendModules(entities, {
|
|
300
319
|
dir: input.dir,
|
|
301
320
|
root,
|
|
302
321
|
projectRoot: input.baseDir ?? input.dir,
|
|
322
|
+
...(binary !== undefined ? { modeOptions: { binary } } : {}),
|
|
303
323
|
});
|
|
304
324
|
for (const [key, entity] of children) entities.set(key, entity);
|
|
305
325
|
return entities;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# documented
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"terraform": {
|
|
3
|
+
"required_providers": {
|
|
4
|
+
"google": { "source": "hashicorp/google", "version": "~> 6.0" }
|
|
5
|
+
}
|
|
6
|
+
},
|
|
7
|
+
"variable": {
|
|
8
|
+
"project": { "type": "string", "description": "The project id." },
|
|
9
|
+
"region": { "type": "string", "default": "us-central1" }
|
|
10
|
+
},
|
|
11
|
+
"output": {
|
|
12
|
+
"name": { "value": "${var.project}", "description": "The project id, echoed." }
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Simple
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
variable "cidr" {
|
|
2
|
+
type = string
|
|
3
|
+
description = "The VPC's IPv4 CIDR block."
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
variable "tags" {
|
|
7
|
+
type = map(string)
|
|
8
|
+
default = {}
|
|
9
|
+
description = "Tags for every resource."
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
variable "flow_log_key" {
|
|
13
|
+
type = string
|
|
14
|
+
default = "not-a-real-key"
|
|
15
|
+
sensitive = true
|
|
16
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a module sits in a Terraform module registry, and how a registry
|
|
3
|
+
* source (`<host>/<namespace>/<name>/<system>`) is split into those parts.
|
|
4
|
+
* Lifted from terragucci's `publish/registry.ts` (18f6431595) for chant#4565.
|
|
5
|
+
* No Node imports, so an edge function can carry it.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const DISCOVERY = ".well-known/terraform.json";
|
|
9
|
+
export const MODULES_V1 = "/v1/modules/";
|
|
10
|
+
export const DEFAULT_SYSTEM = "generic";
|
|
11
|
+
|
|
12
|
+
/** A registry namespace or module name: letters, digits, `-` and `_`, starting and ending on a letter or digit. */
|
|
13
|
+
export const REGISTRY_NAME = /^[0-9A-Za-z](?:[0-9A-Za-z_-]{0,62}[0-9A-Za-z])?$/;
|
|
14
|
+
/** A registry module's system (its target provider): lower-case letters and digits. */
|
|
15
|
+
export const REGISTRY_SYSTEM = /^[0-9a-z]{1,64}$/;
|
|
16
|
+
|
|
17
|
+
/** Where a module is in the registry. */
|
|
18
|
+
export interface RegistryAddress {
|
|
19
|
+
namespace: string;
|
|
20
|
+
name: string;
|
|
21
|
+
system: string;
|
|
22
|
+
/** `<host>/<namespace>/<name>/<system>`, the source a root writes. */
|
|
23
|
+
source: string;
|
|
24
|
+
/** The module's directory under the registry root: `v1/modules/<namespace>/<name>/<system>`. */
|
|
25
|
+
path: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** What placing a module needs from a registry's settings. */
|
|
29
|
+
export interface RegistryPlacement {
|
|
30
|
+
/** The registry's base URL; its host is what sources name. */
|
|
31
|
+
url: string;
|
|
32
|
+
namespace: string;
|
|
33
|
+
/** A namespace per path prefix, the longest prefix winning. */
|
|
34
|
+
namespaces?: Record<string, string>;
|
|
35
|
+
system?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** A module name the protocol cannot carry. */
|
|
39
|
+
export class RegistryNameError extends Error {
|
|
40
|
+
constructor(message: string) {
|
|
41
|
+
super(message);
|
|
42
|
+
this.name = "RegistryNameError";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** The host a registry's sources name: its URL without the scheme, lower-cased. */
|
|
47
|
+
export const registryHost = (reg: Pick<RegistryPlacement, "url">): string => new URL(reg.url).host.toLowerCase();
|
|
48
|
+
|
|
49
|
+
/** The namespace a module's path goes under: the longest `namespaces` prefix it starts with, else `namespace`. */
|
|
50
|
+
export function namespaceFor(reg: Pick<RegistryPlacement, "namespace" | "namespaces">, rel: string): string {
|
|
51
|
+
let best: { prefix: string; ns: string } | undefined;
|
|
52
|
+
for (const [prefix, ns] of Object.entries(reg.namespaces ?? {})) {
|
|
53
|
+
const p = prefix.replace(/^\.\//, "");
|
|
54
|
+
const dir = p.endsWith("/") ? p : `${p}/`;
|
|
55
|
+
if ((rel.startsWith(dir) || rel === p.replace(/\/+$/, "")) && (!best || p.length > best.prefix.length)) best = { prefix: p, ns };
|
|
56
|
+
}
|
|
57
|
+
return best?.ns ?? reg.namespace;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** A module's place in the registry: its namespace, its name (the last segment of its path) and its system. */
|
|
61
|
+
export function registryAddress(reg: RegistryPlacement, rel: string): RegistryAddress {
|
|
62
|
+
const namespace = namespaceFor(reg, rel);
|
|
63
|
+
const name = rel.replace(/\/+$/, "").split("/").pop() ?? "";
|
|
64
|
+
const system = reg.system ?? DEFAULT_SYSTEM;
|
|
65
|
+
if (!REGISTRY_NAME.test(name)) throw new RegistryNameError(`${rel}: a registry module's name is letters, digits, - and _, and ${JSON.stringify(name)} is not; rename the directory`);
|
|
66
|
+
return { namespace, name, system, source: `${registryHost(reg)}/${namespace}/${name}/${system}`, path: `v1/modules/${namespace}/${name}/${system}` };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** A registry source split into its parts. */
|
|
70
|
+
export interface RegistrySource {
|
|
71
|
+
host: string;
|
|
72
|
+
namespace: string;
|
|
73
|
+
name: string;
|
|
74
|
+
system: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A registry source split into its host and module, or undefined when the
|
|
79
|
+
* source is not one: `host/ns/name/system`, with an optional `//subdir` and
|
|
80
|
+
* query. The host must look like one (a dot, a port, or `localhost`), so a
|
|
81
|
+
* three-part public registry source with no host is not taken for one.
|
|
82
|
+
* `hosts` names bare hosts a CLI `host` block declares (a Nexus repository's
|
|
83
|
+
* name, chant#4605), which are taken as hosts too.
|
|
84
|
+
*/
|
|
85
|
+
export function parseRegistrySource(source: string, hosts: readonly string[] = []): RegistrySource | undefined {
|
|
86
|
+
const base = source.split("?")[0]!.split("//")[0]!;
|
|
87
|
+
const m = /^([a-z0-9.-]+(?::\d+)?)\/([^/]+)\/([^/]+)\/([^/]+)$/i.exec(base);
|
|
88
|
+
const known = (h: string) => hosts.some((k) => k.toLowerCase() === h.toLowerCase());
|
|
89
|
+
if (!m || (!m[1]!.includes(".") && !m[1]!.includes(":") && m[1] !== "localhost" && !known(m[1]!))) return undefined;
|
|
90
|
+
return { host: m[1]!.toLowerCase(), namespace: m[2]!, name: m[3]!, system: m[4]! };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** A key under a registry's prefix in its bucket or directory. */
|
|
94
|
+
export const keyFor = (prefix: string | undefined, path: string): string => {
|
|
95
|
+
const p = (prefix ?? "").replace(/^\/+|\/+$/g, "");
|
|
96
|
+
return p ? `${p}/${path}` : path;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/** The tarball's name beside its version. */
|
|
100
|
+
export const tarballName = (addr: Pick<RegistryAddress, "name">, version: string): string => `${addr.name}-${version}.tar.gz`;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading a registry's release catalog (chant#4599, terragucci#1289 bundle
|
|
3
|
+
* B): `catalog/index.json` beside the registry's files, the document
|
|
4
|
+
* `renderCatalogSite` writes (`@intentius/chant/lifecycle/release-catalog-site`).
|
|
5
|
+
*
|
|
6
|
+
* The request carries the token the CLIs would send the host (chant#4563,
|
|
7
|
+
* `readToken` in ./reader.ts), so a registry behind the edge function's
|
|
8
|
+
* `auth: token` check answers it. Per ruling B (2026-10-27) this reader is
|
|
9
|
+
* how a token-protected catalog is read; the edge function gains no cookie
|
|
10
|
+
* and no open path, and a browser reaches the catalog over the
|
|
11
|
+
* network-private path.
|
|
12
|
+
*/
|
|
13
|
+
import { credentialsHost, tokenVariable } from "@intentius/chant/terraform/credentials";
|
|
14
|
+
import { parseReleaseCatalog, ReleaseCatalogError, type ReleaseCatalog } from "@intentius/chant/lifecycle/release-catalog";
|
|
15
|
+
import { readToken, RegistryError, type RegistryFetch, type RegistryReadOptions } from "./reader";
|
|
16
|
+
|
|
17
|
+
/** Where the catalog sits under a registry's root. */
|
|
18
|
+
export const CATALOG_PATH = "catalog/index.json";
|
|
19
|
+
|
|
20
|
+
/** The catalog URL for a registry: a host (`modules.acme.dev`) or a base URL (`https://modules.acme.dev/` or `https://cdn.acme.dev/registry/`). */
|
|
21
|
+
export function catalogUrl(registry: string, scheme: "https" | "http" = "https"): string {
|
|
22
|
+
const base = registry.includes("://") ? registry : `${scheme}://${registry}`;
|
|
23
|
+
return new URL(CATALOG_PATH, base.endsWith("/") ? base : `${base}/`).toString();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Fetch and validate a registry's catalog. Throws `RegistryError` when the
|
|
28
|
+
* request fails or is refused (naming where a token goes, never a value),
|
|
29
|
+
* and when the answer is not a valid catalog. A registry with no catalog
|
|
30
|
+
* (404) gives null.
|
|
31
|
+
*/
|
|
32
|
+
export async function readRegistryCatalog(registry: string, options: RegistryReadOptions = {}): Promise<ReleaseCatalog | null> {
|
|
33
|
+
const url = catalogUrl(registry, options.scheme);
|
|
34
|
+
const host = new URL(url).host.toLowerCase();
|
|
35
|
+
const token = readToken(host, options);
|
|
36
|
+
const fetchFn: RegistryFetch = options.fetch ?? ((u, init) => fetch(u, init));
|
|
37
|
+
let res: Response;
|
|
38
|
+
try {
|
|
39
|
+
res = await fetchFn(url, { method: "GET", redirect: "follow", headers: { Accept: "application/json", ...(token ? { Authorization: `Bearer ${token}` } : {}) } });
|
|
40
|
+
} catch (e) {
|
|
41
|
+
throw new RegistryError(`${url}: ${(e as Error).message}`);
|
|
42
|
+
}
|
|
43
|
+
if (res.status === 404) return null;
|
|
44
|
+
if (res.status === 401 || res.status === 403) {
|
|
45
|
+
const variable = tokenVariable(host);
|
|
46
|
+
const where = variable ? `${variable} or a credentials "${credentialsHost(host)}" block` : `a credentials "${credentialsHost(host) ?? host}" block in credentials.tfrc.json`;
|
|
47
|
+
throw new RegistryError(token ? `${url} answered ${res.status}: the registry refused the token for ${host}` : `${url} answered ${res.status}: the catalog wants a token; set ${where}`);
|
|
48
|
+
}
|
|
49
|
+
if (!res.ok) throw new RegistryError(`${url} answered ${res.status}`);
|
|
50
|
+
try {
|
|
51
|
+
return parseReleaseCatalog(await res.text());
|
|
52
|
+
} catch (e) {
|
|
53
|
+
if (e instanceof ReleaseCatalogError) throw new RegistryError(`${url} is not a release catalog: ${e.problems.slice(0, 3).join("; ")}`);
|
|
54
|
+
throw e;
|
|
55
|
+
}
|
|
56
|
+
}
|