@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,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shape of choudoufu's `live/module-compat.json` (choudoufu#2292,
|
|
3
|
+
* `tools/modcompat/modcompat.go`), as far as the known-module catalog reads
|
|
4
|
+
* it. Only the static tier is typed here; see `./refresh-cli.ts`.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** One refusal on a static row: a choudoufu refusal ID and where it is documented. */
|
|
8
|
+
export interface StaticRefusal {
|
|
9
|
+
id: string;
|
|
10
|
+
layer: string;
|
|
11
|
+
sites: number;
|
|
12
|
+
docs_ref: string;
|
|
13
|
+
docs_url: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** One terraform-aws-modules example measured offline in the onboarded form. */
|
|
17
|
+
export interface StaticRow {
|
|
18
|
+
tier: "static";
|
|
19
|
+
/** Registry address, `terraform-aws-modules/vpc/aws`. */
|
|
20
|
+
module: string;
|
|
21
|
+
/** The module repository's tag, `v6.6.1`. */
|
|
22
|
+
version: string;
|
|
23
|
+
/** The example directory inside the module repository. */
|
|
24
|
+
example: string;
|
|
25
|
+
date: string;
|
|
26
|
+
commit: string;
|
|
27
|
+
aws_provider: string;
|
|
28
|
+
verdict: "clear" | "refused" | "unmeasured";
|
|
29
|
+
/** Eligible data-source reads. These never refuse and are not refusals. */
|
|
30
|
+
reads: number;
|
|
31
|
+
refusals: StaticRefusal[];
|
|
32
|
+
reason?: string;
|
|
33
|
+
partial_schemas?: string[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface StaticSource {
|
|
37
|
+
module: string;
|
|
38
|
+
repo: string;
|
|
39
|
+
version: string;
|
|
40
|
+
commit: string;
|
|
41
|
+
glob: string;
|
|
42
|
+
examples: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** How the static tier was measured. */
|
|
46
|
+
export interface StaticMeasurement {
|
|
47
|
+
date: string;
|
|
48
|
+
commit: string;
|
|
49
|
+
instrument: string;
|
|
50
|
+
form: string;
|
|
51
|
+
schemas: boolean;
|
|
52
|
+
second_pass: boolean;
|
|
53
|
+
aws_provider: string;
|
|
54
|
+
sources: StaticSource[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The parts of the file the catalog reads. */
|
|
58
|
+
export interface ModuleCompatFile {
|
|
59
|
+
schema: number;
|
|
60
|
+
static_measurement: StaticMeasurement;
|
|
61
|
+
static: StaticRow[];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const VERDICTS = new Set(["clear", "refused", "unmeasured"]);
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Check a parsed `live/module-compat.json` against the shape above and return
|
|
68
|
+
* it. Throws on a schema other than 1, a row outside the static tier, or a
|
|
69
|
+
* row whose verdict disagrees with its refusals, so a refresh never vendors a
|
|
70
|
+
* table the catalog would misread.
|
|
71
|
+
*/
|
|
72
|
+
export function parseModuleCompat(raw: unknown): ModuleCompatFile {
|
|
73
|
+
const file = raw as Partial<ModuleCompatFile>;
|
|
74
|
+
if (file?.schema !== 1) throw new Error(`module-compat.json: schema ${String(file?.schema)}, expected 1`);
|
|
75
|
+
if (!file.static_measurement || !Array.isArray(file.static)) {
|
|
76
|
+
throw new Error("module-compat.json: missing static_measurement or static");
|
|
77
|
+
}
|
|
78
|
+
for (const row of file.static) {
|
|
79
|
+
const where = `${row.module} ${row.version} ${row.example}`;
|
|
80
|
+
if (row.tier !== "static") throw new Error(`module-compat.json: ${where} is in the static array with tier ${row.tier}`);
|
|
81
|
+
if (!VERDICTS.has(row.verdict)) throw new Error(`module-compat.json: ${where} has verdict ${row.verdict}`);
|
|
82
|
+
if (!Array.isArray(row.refusals)) throw new Error(`module-compat.json: ${where} has no refusals list`);
|
|
83
|
+
if ((row.verdict === "refused") !== (row.refusals.length > 0)) {
|
|
84
|
+
throw new Error(`module-compat.json: ${where} is ${row.verdict} with ${row.refusals.length} refusals`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return { schema: file.schema, static_measurement: file.static_measurement, static: file.static };
|
|
88
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `choudoufuPlanSet` as an Op activity (#4483, H3 of #4477). One Op plans two
|
|
3
|
+
* live choudoufu roots, one per cloud, and hands each root's `changeSet` to
|
|
4
|
+
* `composeChangeSet`, the shape behold's three-cloud front door takes instead
|
|
5
|
+
* of composing the change set in a script.
|
|
6
|
+
*
|
|
7
|
+
* The activity is the real one, resolved through `loadActivities`, so it runs
|
|
8
|
+
* the configured binary. A fake `choudoufu` on `PATH` answers `version` and
|
|
9
|
+
* prints a one-root set plan document for `live-plan-set`, exiting 2 as
|
|
10
|
+
* choudoufu does for a plan with changes. Nothing reaches a cloud.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { chmodSync, mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
14
|
+
import { tmpdir } from "node:os";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { afterAll, afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
17
|
+
import { composeChangeSet, loadActivities, runOpLocally, validateActivitySteps, validateStepOutputRefs, type ActivityProfile, type OpConfig } from "@intentius/chant/op";
|
|
18
|
+
import { choudoufuPlanSet } from "../builders";
|
|
19
|
+
import * as contracts from "../activity-contracts";
|
|
20
|
+
import { __resetChoudoufuVersionCheckForTests } from "./terraform";
|
|
21
|
+
|
|
22
|
+
const scratch: string[] = [];
|
|
23
|
+
afterAll(() => {
|
|
24
|
+
for (const d of scratch) rmSync(d, { recursive: true, force: true });
|
|
25
|
+
});
|
|
26
|
+
beforeEach(() => __resetChoudoufuVersionCheckForTests());
|
|
27
|
+
afterEach(() => vi.unstubAllEnvs());
|
|
28
|
+
|
|
29
|
+
const PROFILES: Record<string, ActivityProfile> = {
|
|
30
|
+
longInfra: { timeout: "5m", retry: { maximumAttempts: 1 } },
|
|
31
|
+
fastIdempotent: { timeout: "5m", retry: { maximumAttempts: 1 } },
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/** A fake choudoufu: `version`, and `live-plan-set -json -out-dir=<d> <root>` printing a one-root document. */
|
|
35
|
+
const FAKE = `#!/bin/sh
|
|
36
|
+
if [ "$1" = "version" ]; then echo "choudoufu v0.31.0 (based on OpenTofu v1.13.0)"; exit 0; fi
|
|
37
|
+
if [ "$1" = "live-plan-set" ]; then
|
|
38
|
+
for a in "$@"; do root="$a"; done
|
|
39
|
+
name=$(basename "$root")
|
|
40
|
+
cat <<EOF
|
|
41
|
+
{"format_version":"1","roots":[{"root":"$root","estate":"$name","status":"planned","error":"","changes":true,"plan":{"format_version":"1.2","resource_changes":[{"address":"null_resource.$name","mode":"managed","type":"null_resource","name":"$name","change":{"actions":["create"],"before":null,"after":{}}}]},"digest":"sha256:root-$name"}],"summary":{"roots":1,"planned":1,"changed":1,"failed":0},"digest":"sha256:set-$name","exit_code":2}
|
|
42
|
+
EOF
|
|
43
|
+
exit 2
|
|
44
|
+
fi
|
|
45
|
+
echo "fake choudoufu: unexpected $*" >&2
|
|
46
|
+
exit 1
|
|
47
|
+
`;
|
|
48
|
+
|
|
49
|
+
function project(): string {
|
|
50
|
+
const dir = realpathSync(mkdtempSync(join(tmpdir(), "chant-plan-set-op-")));
|
|
51
|
+
scratch.push(dir);
|
|
52
|
+
const bin = join(dir, "bin");
|
|
53
|
+
mkdirSync(bin);
|
|
54
|
+
writeFileSync(join(bin, "choudoufu"), FAKE);
|
|
55
|
+
chmodSync(join(bin, "choudoufu"), 0o755);
|
|
56
|
+
vi.stubEnv("PATH", `${bin}:${process.env.PATH ?? ""}`);
|
|
57
|
+
for (const root of ["aws", "azure"]) {
|
|
58
|
+
mkdirSync(join(dir, "estates", root), { recursive: true });
|
|
59
|
+
writeFileSync(join(dir, "estates", root, "main.tf"), "");
|
|
60
|
+
}
|
|
61
|
+
writeFileSync(
|
|
62
|
+
join(dir, "chant.config.json"),
|
|
63
|
+
JSON.stringify({ lexicons: ["terraform"], terraform: { binary: "choudoufu", roots: { aws: { dir: "estates/aws" }, azure: { dir: "estates/azure" } } } }),
|
|
64
|
+
);
|
|
65
|
+
return dir;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function frontDoor(cwd: string): OpConfig {
|
|
69
|
+
const aws = choudoufuPlanSet("aws", { cwd, id: "aws" });
|
|
70
|
+
const azure = choudoufuPlanSet("azure", { cwd, id: "azure" });
|
|
71
|
+
return {
|
|
72
|
+
name: "front-door-plan",
|
|
73
|
+
overview: "",
|
|
74
|
+
phases: [
|
|
75
|
+
{ name: "Plan", steps: [aws, azure] },
|
|
76
|
+
{ name: "Compose", steps: [composeChangeSet({ parts: [aws.out.changeSet, azure.out.changeSet], id: "doc" })] },
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
describe("choudoufuPlanSet as an Op activity (#4483)", () => {
|
|
82
|
+
test("is resolved from the terraform lexicon's activities", async () => {
|
|
83
|
+
const activities = await loadActivities(["terraform"]);
|
|
84
|
+
expect(typeof activities.get("choudoufuPlanSet")).toBe("function");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("its contract validates the steps and the changeSet references", () => {
|
|
88
|
+
const map = new Map(Object.values(contracts).map((c) => [c.name, c]));
|
|
89
|
+
const config = frontDoor("/tmp/x");
|
|
90
|
+
expect(validateActivitySteps(config, map)).toEqual([]);
|
|
91
|
+
expect(validateStepOutputRefs(config, map)).toEqual([]);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("an Op plans two clouds' roots and composes one change set from their parts", async () => {
|
|
95
|
+
const dir = project();
|
|
96
|
+
const activities = await loadActivities(["terraform"]);
|
|
97
|
+
const compose = activities.get("composeChangeSet")!;
|
|
98
|
+
const documents: Array<{ document: { members?: Array<{ member: string }> }; digest: string }> = [];
|
|
99
|
+
activities.set("composeChangeSet", async (args, signal) => {
|
|
100
|
+
const out = (await compose(args, signal)) as (typeof documents)[number];
|
|
101
|
+
documents.push(out);
|
|
102
|
+
return out;
|
|
103
|
+
});
|
|
104
|
+
const result = await runOpLocally(frontDoor(dir), activities, PROFILES);
|
|
105
|
+
expect(result.status).toBe("ok");
|
|
106
|
+
expect(result.records.filter((r) => r.fn === "choudoufuPlanSet").map((r) => r.status)).toEqual(["ok", "ok"]);
|
|
107
|
+
expect(documents).toHaveLength(1);
|
|
108
|
+
expect(documents[0]!.digest).toMatch(/^jcs1-sha256:[0-9a-f]{64}$/);
|
|
109
|
+
expect((documents[0]!.document.members ?? []).map((m) => m.member).sort()).toEqual(["aws", "azure"]);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
* - choudoufuLiveLs: `live-ls -estate=<estate> -json [-consistent]` (#2103).
|
|
17
17
|
* - choudoufuLiveCheck: `live-check -json`, no cloud calls (#2103).
|
|
18
18
|
* - choudoufuAdopt: the tag writes that claim an adoption ledger's matches (#2105).
|
|
19
|
+
* - choudoufuPlanSet: `live-plan-set -json` over one live root, as a
|
|
20
|
+
* one-root set (#3459). Its `changeSet` is the root's part, so an Op can
|
|
21
|
+
* plan several clouds' roots and hand the parts to `composeChangeSet`
|
|
22
|
+
* (#4483).
|
|
19
23
|
* - terraformPinRollout: one run of a pin-bump rollout, opening at most one
|
|
20
24
|
* wave's pull request (#3189). It loads the HCL parser on first call.
|
|
21
25
|
*
|
|
@@ -34,6 +38,8 @@ export {
|
|
|
34
38
|
choudoufuLiveLs,
|
|
35
39
|
choudoufuLiveCheck,
|
|
36
40
|
choudoufuAdopt,
|
|
41
|
+
choudoufuPlanSet,
|
|
42
|
+
choudoufuPlanSetCommand,
|
|
37
43
|
terraformInitCommand,
|
|
38
44
|
terraformPlanCommand,
|
|
39
45
|
terraformApplyCommand,
|
|
@@ -52,6 +58,7 @@ export {
|
|
|
52
58
|
DEFAULT_TERRAFORM_BINARY,
|
|
53
59
|
DEFAULT_LIVE_PLAN_DOCUMENT_FILE,
|
|
54
60
|
MIN_CHOUDOUFU_VERSION,
|
|
61
|
+
MIN_CHOUDOUFU_ESTATES_VERSION,
|
|
55
62
|
classifyApprovalRefusal,
|
|
56
63
|
CHOUDOUFU_LIVE_PLAN_OUT_REFUSAL,
|
|
57
64
|
CHOUDOUFU_APPROVAL_EXIT_CODE,
|
|
@@ -78,6 +85,8 @@ export type {
|
|
|
78
85
|
ChoudoufuLiveLsResult,
|
|
79
86
|
ChoudoufuLiveCheckResult,
|
|
80
87
|
ChoudoufuAdoptResult,
|
|
88
|
+
ChoudoufuPlanSet,
|
|
89
|
+
ChoudoufuPlanSetResult,
|
|
81
90
|
AdoptionRefusal,
|
|
82
91
|
PlanChangeCounts,
|
|
83
92
|
LivePlanUnownedCounts,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A fast, regex-based read of whether a root module directory declares a
|
|
3
3
|
* live estate: an `estate.chdf.hcl` sidecar, or a `live { ... }` block nested
|
|
4
|
-
* inside a `terraform { ... }` block of some
|
|
4
|
+
* inside a `terraform { ... }` block of some configuration file (#2103), the
|
|
5
|
+
* `terraform` object of a `.tf.json` file included (chant#4504).
|
|
5
6
|
*
|
|
6
7
|
* Deliberately separate from `../../hcl/parse.ts`'s AST-accurate detection
|
|
7
8
|
* (`blocksToEntities`'s `liveBlocksIn`), which the build and lint paths use.
|
|
@@ -17,8 +18,38 @@
|
|
|
17
18
|
* reason.
|
|
18
19
|
*/
|
|
19
20
|
|
|
20
|
-
import { existsSync, readFileSync
|
|
21
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
21
22
|
import { join } from "node:path";
|
|
23
|
+
import { isJsonConfigFile, jsonLiveBlocks, listConfigFiles } from "../../hcl/files";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The configuration files of `dir` a live check reads, in filename order.
|
|
27
|
+
* A `live` block takes effect only under choudoufu, so the set is the one
|
|
28
|
+
* choudoufu reads (`.tf`, `.tf.json`, `.tofu` and `.tofu.json`, `x.tofu`
|
|
29
|
+
* over `x.tf`) from the lexicon's one lister (chant#4457), which reads the
|
|
30
|
+
* directory and nothing else.
|
|
31
|
+
*/
|
|
32
|
+
function liveFiles(dir: string, binary: string): string[] {
|
|
33
|
+
return listConfigFiles(dir, binary);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The `live` block bodies of one file: a JSON-syntax file's from its
|
|
38
|
+
* `terraform` blocks (chant#4504), an HCL file's first one by brace counting.
|
|
39
|
+
* HCL bodies come back as text and JSON ones as objects.
|
|
40
|
+
*/
|
|
41
|
+
function liveBlocksOf(name: string, source: string): Array<string | Record<string, unknown>> {
|
|
42
|
+
if (isJsonConfigFile(name)) return jsonLiveBlocks(source);
|
|
43
|
+
const terraformBlock = extractBalancedBlock(source, "terraform");
|
|
44
|
+
if (terraformBlock === undefined) return [];
|
|
45
|
+
const liveBlock = extractBalancedBlock(terraformBlock, "live");
|
|
46
|
+
return liveBlock === undefined ? [] : [liveBlock];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** A non-empty string, or undefined. */
|
|
50
|
+
function nonEmpty(v: unknown): string | undefined {
|
|
51
|
+
return typeof v === "string" && v !== "" ? v : undefined;
|
|
52
|
+
}
|
|
22
53
|
|
|
23
54
|
/** Kept in sync with `LIVE_SIDECAR_FILENAME` in `../../hcl/parse.ts`. */
|
|
24
55
|
const LIVE_SIDECAR_FILENAME = "estate.chdf.hcl";
|
|
@@ -69,7 +100,7 @@ function extractQuotedAttr(body: string, key: string): string | undefined {
|
|
|
69
100
|
* no sidecar (or one this function cannot read) yields `undefined` rather
|
|
70
101
|
* than throwing, since this is a best-effort check, not the authoritative parse.
|
|
71
102
|
*/
|
|
72
|
-
export function detectLiveEstate(dir: string): string | undefined {
|
|
103
|
+
export function detectLiveEstate(dir: string, binary = "choudoufu"): string | undefined {
|
|
73
104
|
const sidecarPath = join(dir, LIVE_SIDECAR_FILENAME);
|
|
74
105
|
if (existsSync(sidecarPath)) {
|
|
75
106
|
try {
|
|
@@ -82,9 +113,7 @@ export function detectLiveEstate(dir: string): string | undefined {
|
|
|
82
113
|
|
|
83
114
|
let names: string[];
|
|
84
115
|
try {
|
|
85
|
-
names =
|
|
86
|
-
.filter((f) => f.endsWith(".tf"))
|
|
87
|
-
.sort();
|
|
116
|
+
names = liveFiles(dir, binary);
|
|
88
117
|
} catch {
|
|
89
118
|
return undefined;
|
|
90
119
|
}
|
|
@@ -96,12 +125,10 @@ export function detectLiveEstate(dir: string): string | undefined {
|
|
|
96
125
|
} catch {
|
|
97
126
|
continue;
|
|
98
127
|
}
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const estate = extractEstateAttr(liveBlock);
|
|
104
|
-
if (estate) return estate;
|
|
128
|
+
for (const liveBlock of liveBlocksOf(name, source)) {
|
|
129
|
+
const estate = typeof liveBlock === "string" ? extractEstateAttr(liveBlock) : nonEmpty(liveBlock.estate);
|
|
130
|
+
if (estate) return estate;
|
|
131
|
+
}
|
|
105
132
|
}
|
|
106
133
|
|
|
107
134
|
return undefined;
|
|
@@ -129,12 +156,10 @@ export interface LivePolicyVerbs {
|
|
|
129
156
|
undeclaredUntagged?: string;
|
|
130
157
|
}
|
|
131
158
|
|
|
132
|
-
export function detectLivePolicyVerbs(dir: string): LivePolicyVerbs | undefined {
|
|
159
|
+
export function detectLivePolicyVerbs(dir: string, binary = "choudoufu"): LivePolicyVerbs | undefined {
|
|
133
160
|
let names: string[];
|
|
134
161
|
try {
|
|
135
|
-
names =
|
|
136
|
-
.filter((f) => f.endsWith(".tf"))
|
|
137
|
-
.sort();
|
|
162
|
+
names = liveFiles(dir, binary);
|
|
138
163
|
} catch {
|
|
139
164
|
return undefined;
|
|
140
165
|
}
|
|
@@ -146,16 +171,20 @@ export function detectLivePolicyVerbs(dir: string): LivePolicyVerbs | undefined
|
|
|
146
171
|
} catch {
|
|
147
172
|
continue;
|
|
148
173
|
}
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
174
|
+
for (const liveBlock of liveBlocksOf(name, source)) {
|
|
175
|
+
if (typeof liveBlock === "string") {
|
|
176
|
+
const policyBlock = extractBalancedBlock(liveBlock, "policy");
|
|
177
|
+
if (policyBlock === undefined) continue;
|
|
178
|
+
return {
|
|
179
|
+
undeclaredTagged: extractQuotedAttr(policyBlock, "undeclared_tagged"),
|
|
180
|
+
undeclaredUntagged: extractQuotedAttr(policyBlock, "undeclared_untagged"),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// JSON syntax writes the nested `policy` block as one object or an array of them.
|
|
184
|
+
const policy = [liveBlock.policy].flat().find((p): p is Record<string, unknown> => typeof p === "object" && p !== null && !Array.isArray(p));
|
|
185
|
+
if (!policy) continue;
|
|
186
|
+
return { undeclaredTagged: nonEmpty(policy.undeclared_tagged), undeclaredUntagged: nonEmpty(policy.undeclared_untagged) };
|
|
187
|
+
}
|
|
159
188
|
}
|
|
160
189
|
|
|
161
190
|
return undefined;
|
|
@@ -41,6 +41,8 @@ export interface TerraformPinRolloutArgs {
|
|
|
41
41
|
appliedCheck?: string;
|
|
42
42
|
/** A directory in the repository. Default: the working directory. */
|
|
43
43
|
cwd?: string;
|
|
44
|
+
/** The binary the roots run, which says whether their `.tofu` files are read (chant#4457). Default `terraform`. */
|
|
45
|
+
binary?: string;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
export type TerraformPinRolloutResult = PinRolloutResult;
|
|
@@ -73,5 +75,6 @@ export async function readPinRollout(args: TerraformPinRolloutArgs): Promise<Ter
|
|
|
73
75
|
...(args.base ? { base: args.base } : {}),
|
|
74
76
|
...(args.remote ? { remote: args.remote } : {}),
|
|
75
77
|
...(args.appliedCheck ? { appliedCheck: args.appliedCheck } : {}),
|
|
78
|
+
...(args.binary ? { binary: args.binary } : {}),
|
|
76
79
|
});
|
|
77
80
|
}
|
|
@@ -15,7 +15,7 @@ import { describe, test, expect } from "vitest";
|
|
|
15
15
|
import { loadActivities, resolveActivity } from "@intentius/chant/op";
|
|
16
16
|
|
|
17
17
|
describe("loadActivities([\"terraform\"]) (#2086, #2103)", () => {
|
|
18
|
-
test("resolves
|
|
18
|
+
test("resolves its activity names", async () => {
|
|
19
19
|
const activities = await loadActivities(["terraform"]);
|
|
20
20
|
for (const name of [
|
|
21
21
|
"terraformInit",
|
|
@@ -25,6 +25,7 @@ describe("loadActivities([\"terraform\"]) (#2086, #2103)", () => {
|
|
|
25
25
|
"choudoufuLivePlan",
|
|
26
26
|
"choudoufuLiveLs",
|
|
27
27
|
"choudoufuLiveCheck",
|
|
28
|
+
"choudoufuPlanSet",
|
|
28
29
|
]) {
|
|
29
30
|
expect(typeof resolveActivity(activities, name)).toBe("function");
|
|
30
31
|
}
|
|
@@ -183,6 +183,22 @@ describe("terraformInitCommand (#2086)", () => {
|
|
|
183
183
|
).toBe("tofu init -input=false -backend-config=bucket=tf-state -backend-config=key=app/terraform.tfstate");
|
|
184
184
|
});
|
|
185
185
|
|
|
186
|
+
test("backendConfigFiles become -backend-config=<path> flags, in order and before the pairs (chant#4459)", () => {
|
|
187
|
+
expect(
|
|
188
|
+
terraformInitCommand({
|
|
189
|
+
binary: "tofu",
|
|
190
|
+
backendConfig: { key: "app/terraform.tfstate" },
|
|
191
|
+
backendConfigFiles: ["backend.hcl", "/etc/chant/shared.hcl"],
|
|
192
|
+
}),
|
|
193
|
+
).toBe("tofu init -input=false -backend-config=backend.hcl -backend-config=/etc/chant/shared.hcl -backend-config=key=app/terraform.tfstate");
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("the init line a refusal prints carries the files too, relative to the root it -chdirs into (chant#4459)", () => {
|
|
197
|
+
expect(terraformInitLine({ binary: "terraform", dir: "/repo/roots/app", backendConfigFiles: ["backend.hcl"], backendConfig: { key: "k" } })).toBe(
|
|
198
|
+
"terraform -chdir=/repo/roots/app init -input=false -backend-config=backend.hcl -backend-config=key=k",
|
|
199
|
+
);
|
|
200
|
+
});
|
|
201
|
+
|
|
186
202
|
test("-upgrade and -reconfigure are opt-in", () => {
|
|
187
203
|
expect(terraformInitCommand({ binary: "terraform", upgrade: true, reconfigure: true })).toBe(
|
|
188
204
|
"terraform init -input=false -upgrade -reconfigure",
|
|
@@ -408,6 +424,32 @@ describe("terraformInit (#2086)", () => {
|
|
|
408
424
|
expect(execCalls[0].opts.env?.TF_WORKSPACE).toBe("prod");
|
|
409
425
|
expect(result.workspace).toBe("prod");
|
|
410
426
|
});
|
|
427
|
+
|
|
428
|
+
test("a failed init carries the root it resolved as known outputs (chant#4512)", async () => {
|
|
429
|
+
const dir = project({ roots: { app: { dir: "./infra", workspace: "prod" } } });
|
|
430
|
+
// A workspace root, so the root has a workspace-relative path to publish.
|
|
431
|
+
// The walk up to it stops at the git root, so the project is one.
|
|
432
|
+
mkdirSync(join(dir, ".git"));
|
|
433
|
+
writeFileSync(join(dir, "chant.workspace.json"), JSON.stringify({ name: "w", schema: 1, members: [{ name: "app", dir: ".", kind: "chant" }] }));
|
|
434
|
+
replies.push({ match: "init", reply: execError(1, "Error: Failed to get existing workspaces: backend unreachable") });
|
|
435
|
+
const failure = await terraformInit({ root: "app", cwd: dir }).then(
|
|
436
|
+
() => undefined,
|
|
437
|
+
(err: unknown) => err,
|
|
438
|
+
);
|
|
439
|
+
expect(failure).toBeInstanceOf(Error);
|
|
440
|
+
expect((failure as { knownOutputs?: unknown }).knownOutputs).toEqual({ dir: resolve(dir, "infra"), workspace: "prod", rootPath: "infra" });
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
test("a root that does not resolve fails with no known outputs (chant#4512)", async () => {
|
|
444
|
+
const dir = project({ roots: { app: { dir: "./infra" } } });
|
|
445
|
+
const failure = await terraformInit({ root: "nope", cwd: dir }).then(
|
|
446
|
+
() => undefined,
|
|
447
|
+
(err: unknown) => err,
|
|
448
|
+
);
|
|
449
|
+
expect(failure).toBeInstanceOf(Error);
|
|
450
|
+
expect(failure).not.toHaveProperty("knownOutputs");
|
|
451
|
+
expect(execCalls).toHaveLength(0);
|
|
452
|
+
});
|
|
411
453
|
});
|
|
412
454
|
|
|
413
455
|
// ── terraformPlan ───────────────────────────────────────────────────────────
|
|
@@ -429,6 +471,19 @@ describe("terraformPlan — the -detailed-exitcode mapping (#2086)", () => {
|
|
|
429
471
|
]);
|
|
430
472
|
});
|
|
431
473
|
|
|
474
|
+
test("text: false runs show -json alone, and the result's text is empty (#4479)", async () => {
|
|
475
|
+
const dir = project({ roots: { app: { dir: "./infra" } } });
|
|
476
|
+
showReplies();
|
|
477
|
+
const result = await terraformPlan({ root: "app", cwd: dir, text: false });
|
|
478
|
+
expect(result.text).toBe("");
|
|
479
|
+
expect(result.json).toEqual(JSON.parse(PLAN_JSON));
|
|
480
|
+
expect(result.planDigest).toBe(terraformPlanDigest(JSON.parse(PLAN_JSON)));
|
|
481
|
+
expect(execCalls.map((c) => c.cmd)).toEqual([
|
|
482
|
+
"terraform plan -input=false -detailed-exitcode -out=chant.tfplan",
|
|
483
|
+
"terraform show -json chant.tfplan",
|
|
484
|
+
]);
|
|
485
|
+
});
|
|
486
|
+
|
|
432
487
|
// #2300 — the Plan phase is where the plan gets its identity, so the
|
|
433
488
|
// activity's own result carries it and the Gate step references it from
|
|
434
489
|
// there rather than re-reading the file.
|