@intentius/chant 0.124.51 → 0.124.54
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/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/discover.js +3 -1
- package/dist/behaviour.d.ts +1 -1
- package/dist/behaviour.d.ts.map +1 -1
- package/dist/capabilities/templates.d.ts +65 -0
- package/dist/capabilities/templates.d.ts.map +1 -0
- package/dist/capabilities/templates.js +193 -0
- package/dist/capabilities/templates.json +145 -0
- package/dist/change-set-graph.d.ts +35 -3
- package/dist/change-set-graph.d.ts.map +1 -1
- package/dist/change-set-graph.js +60 -9
- package/dist/change-set.d.ts +65 -7
- package/dist/change-set.d.ts.map +1 -1
- package/dist/change-set.js +23 -12
- package/dist/ci-identity.d.ts +7 -2
- package/dist/ci-identity.d.ts.map +1 -1
- package/dist/ci-identity.js +4 -1
- package/dist/cli/commands/import-index.d.ts +52 -0
- package/dist/cli/commands/import-index.d.ts.map +1 -0
- package/dist/cli/commands/import-index.js +226 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +4 -2
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/components.js +11 -2
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +16 -3
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/graph.js +22 -4
- package/dist/cli/handlers/index-cloud.d.ts +14 -0
- package/dist/cli/handlers/index-cloud.d.ts.map +1 -0
- package/dist/cli/handlers/index-cloud.js +22 -0
- package/dist/cli/handlers/index-diff.d.ts +18 -0
- package/dist/cli/handlers/index-diff.d.ts.map +1 -0
- package/dist/cli/handlers/index-diff.js +142 -0
- package/dist/cli/handlers/lifecycle-drift.d.ts +25 -0
- package/dist/cli/handlers/lifecycle-drift.d.ts.map +1 -0
- package/dist/cli/handlers/lifecycle-drift.js +64 -0
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.js +188 -28
- package/dist/cli/handlers/misc.d.ts +9 -0
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/misc.js +77 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +17 -3
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +89 -15
- package/dist/cli/handlers/query.d.ts.map +1 -1
- package/dist/cli/handlers/query.js +28 -4
- package/dist/cli/handlers/scenario.d.ts.map +1 -1
- package/dist/cli/handlers/scenario.js +8 -7
- package/dist/cli/handlers/search.d.ts +34 -4
- package/dist/cli/handlers/search.d.ts.map +1 -1
- package/dist/cli/handlers/search.js +216 -36
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +55 -1
- package/dist/cli/mcp/lifecycle-tools.d.ts.map +1 -1
- package/dist/cli/mcp/lifecycle-tools.js +3 -2
- package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
- package/dist/cli/mcp/resource-handlers.js +4 -3
- package/dist/cli/mcp/workspace-tools.js +1 -1
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +55 -2
- package/dist/cli/registry.d.ts +19 -1
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cloud-lister/aws.d.ts +35 -0
- package/dist/cloud-lister/aws.d.ts.map +1 -0
- package/dist/cloud-lister/aws.js +203 -0
- package/dist/cloud-lister/azure.d.ts +34 -0
- package/dist/cloud-lister/azure.d.ts.map +1 -0
- package/dist/cloud-lister/azure.js +129 -0
- package/dist/cloud-lister/common.d.ts +40 -0
- package/dist/cloud-lister/common.d.ts.map +1 -0
- package/dist/cloud-lister/common.js +83 -0
- package/dist/cloud-lister/credentials.d.ts +50 -0
- package/dist/cloud-lister/credentials.d.ts.map +1 -0
- package/dist/cloud-lister/credentials.js +86 -0
- package/dist/cloud-lister/fakes.d.ts +27 -0
- package/dist/cloud-lister/fakes.d.ts.map +1 -0
- package/dist/cloud-lister/fakes.js +50 -0
- package/dist/cloud-lister/gcp.d.ts +42 -0
- package/dist/cloud-lister/gcp.d.ts.map +1 -0
- package/dist/cloud-lister/gcp.js +143 -0
- package/dist/cloud-lister/guard.d.ts +49 -0
- package/dist/cloud-lister/guard.d.ts.map +1 -0
- package/dist/cloud-lister/guard.js +103 -0
- package/dist/cloud-lister/ids.d.ts +23 -0
- package/dist/cloud-lister/ids.d.ts.map +1 -0
- package/dist/cloud-lister/ids.js +42 -0
- package/dist/cloud-lister/index.d.ts +67 -0
- package/dist/cloud-lister/index.d.ts.map +1 -0
- package/dist/cloud-lister/index.js +102 -0
- package/dist/cloud-lister/kubernetes.d.ts +64 -0
- package/dist/cloud-lister/kubernetes.d.ts.map +1 -0
- package/dist/cloud-lister/kubernetes.js +276 -0
- package/dist/cloud-lister/markers.d.ts +31 -0
- package/dist/cloud-lister/markers.d.ts.map +1 -0
- package/dist/cloud-lister/markers.js +73 -0
- package/dist/cloud-lister/mask.d.ts +31 -0
- package/dist/cloud-lister/mask.d.ts.map +1 -0
- package/dist/cloud-lister/mask.js +74 -0
- package/dist/cloud-lister/sigv4.d.ts +29 -0
- package/dist/cloud-lister/sigv4.d.ts.map +1 -0
- package/dist/cloud-lister/sigv4.js +54 -0
- package/dist/cloud-lister/transport.d.ts +55 -0
- package/dist/cloud-lister/transport.d.ts.map +1 -0
- package/dist/cloud-lister/transport.js +86 -0
- package/dist/cloud-lister/types.d.ts +121 -0
- package/dist/cloud-lister/types.d.ts.map +1 -0
- package/dist/cloud-lister/types.js +24 -0
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.js +6 -0
- package/dist/components/capability-plugin.d.ts +9 -0
- package/dist/components/capability-plugin.d.ts.map +1 -1
- package/dist/components/capability.d.ts +224 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +21 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +58 -14
- package/dist/components/covered-round.d.ts +173 -0
- package/dist/components/covered-round.d.ts.map +1 -0
- package/dist/components/covered-round.js +200 -0
- package/dist/components/declared-reads.d.ts +38 -0
- package/dist/components/declared-reads.d.ts.map +1 -0
- package/dist/components/declared-reads.js +131 -0
- package/dist/components/deploy-units.d.ts.map +1 -1
- package/dist/components/deploy-units.js +4 -0
- package/dist/components/driver.d.ts +42 -1
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +74 -3
- package/dist/components/fan-out-run.d.ts +23 -1
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +82 -14
- package/dist/components/fan-out-support.d.ts +6 -0
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/fan-out-support.js +4 -1
- package/dist/components/fan-out.d.ts +28 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/groups.d.ts +229 -0
- package/dist/components/groups.d.ts.map +1 -0
- package/dist/components/groups.js +760 -0
- package/dist/components/index.d.ts +7 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +5 -0
- package/dist/components/plan-shape-conformance.d.ts +48 -0
- package/dist/components/plan-shape-conformance.d.ts.map +1 -0
- package/dist/components/plan-shape-conformance.js +122 -0
- package/dist/components/pr-run.d.ts +62 -7
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +354 -53
- package/dist/components/promote-rounds.d.ts +9 -0
- package/dist/components/promote-rounds.d.ts.map +1 -1
- package/dist/components/promote-rounds.js +23 -2
- package/dist/components/promote.d.ts +17 -0
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +36 -6
- package/dist/components/release-gate.d.ts +23 -1
- package/dist/components/release-gate.d.ts.map +1 -1
- package/dist/components/release-gate.js +97 -33
- package/dist/components/run-groups.d.ts +58 -0
- package/dist/components/run-groups.d.ts.map +1 -0
- package/dist/components/run-groups.js +78 -0
- package/dist/components/starter-plugin.d.ts +1 -0
- package/dist/components/starter-plugin.d.ts.map +1 -1
- package/dist/components/starter-plugin.js +6 -1
- package/dist/components/verbs/index.d.ts +1 -0
- package/dist/components/verbs/index.d.ts.map +1 -1
- package/dist/components/verbs/index.js +1 -0
- package/dist/components/verbs/member-outputs.d.ts +187 -0
- package/dist/components/verbs/member-outputs.d.ts.map +1 -0
- package/dist/components/verbs/member-outputs.js +218 -0
- package/dist/components/wave-plan.d.ts +2 -0
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +4 -1
- package/dist/config.d.ts +60 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +27 -0
- package/dist/deep-observation.d.ts +1 -13
- package/dist/deep-observation.d.ts.map +1 -1
- package/dist/deep-observation.js +5 -22
- package/dist/drift-record.d.ts +542 -0
- package/dist/drift-record.d.ts.map +1 -0
- package/dist/drift-record.js +886 -0
- package/dist/engine-facts.d.ts +144 -0
- package/dist/engine-facts.d.ts.map +1 -0
- package/dist/engine-facts.js +14 -0
- package/dist/graph-ir.d.ts +153 -2
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-ir.js +224 -6
- package/dist/graph-refs.d.ts +145 -0
- package/dist/graph-refs.d.ts.map +1 -1
- package/dist/graph-refs.js +305 -0
- package/dist/graph-schema/fixtures/adopt.json +15 -0
- package/dist/graph-schema/fixtures/choudoufu.engine-graph.json +169 -0
- package/dist/graph-schema/fixtures/index.json +68 -0
- package/dist/graph-schema/fixtures/plunge.engine-graph.json +158 -0
- package/dist/graph-schema/fixtures.d.ts +23 -0
- package/dist/graph-schema/fixtures.d.ts.map +1 -0
- package/dist/graph-schema/fixtures.js +246 -0
- package/dist/graph-schema/generate.d.ts +15 -0
- package/dist/graph-schema/generate.d.ts.map +1 -0
- package/dist/graph-schema/generate.js +267 -0
- package/dist/graph-schema/graph.schema.json +1387 -0
- package/dist/health.schema.json +2 -1
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/instance-nodes.d.ts +159 -0
- package/dist/instance-nodes.d.ts.map +1 -0
- package/dist/instance-nodes.js +231 -0
- package/dist/lexicon.d.ts +72 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/adoption-file.d.ts +56 -0
- package/dist/lifecycle/adoption-file.d.ts.map +1 -0
- package/dist/lifecycle/adoption-file.js +123 -0
- package/dist/lifecycle/cloud-index.d.ts +186 -0
- package/dist/lifecycle/cloud-index.d.ts.map +1 -0
- package/dist/lifecycle/cloud-index.js +618 -0
- package/dist/lifecycle/derive-edges.d.ts +59 -0
- package/dist/lifecycle/derive-edges.d.ts.map +1 -0
- package/dist/lifecycle/derive-edges.js +126 -0
- package/dist/lifecycle/git.d.ts +10 -9
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/git.js +7 -1
- package/dist/lifecycle/identity-match.d.ts +133 -0
- package/dist/lifecycle/identity-match.d.ts.map +1 -0
- package/dist/lifecycle/identity-match.js +147 -0
- package/dist/lifecycle/index-diff.d.ts +224 -0
- package/dist/lifecycle/index-diff.d.ts.map +1 -0
- package/dist/lifecycle/index-diff.js +327 -0
- package/dist/lifecycle/index-document.d.ts +130 -0
- package/dist/lifecycle/index-document.d.ts.map +1 -0
- package/dist/lifecycle/index-document.js +189 -0
- package/dist/lifecycle/index-drift.d.ts +121 -0
- package/dist/lifecycle/index-drift.d.ts.map +1 -0
- package/dist/lifecycle/index-drift.js +178 -0
- package/dist/lifecycle/index-import.d.ts +168 -0
- package/dist/lifecycle/index-import.d.ts.map +1 -0
- package/dist/lifecycle/index-import.js +515 -0
- package/dist/lifecycle/index-join.d.ts +129 -0
- package/dist/lifecycle/index-join.d.ts.map +1 -0
- package/dist/lifecycle/index-join.js +248 -0
- package/dist/lifecycle/index.d.ts +4 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/index.js +4 -0
- package/dist/lifecycle/observation-baseline.d.ts +61 -21
- package/dist/lifecycle/observation-baseline.d.ts.map +1 -1
- package/dist/lifecycle/observation-baseline.js +144 -19
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/observe.js +6 -1
- package/dist/lifecycle/query.d.ts +45 -4
- package/dist/lifecycle/query.d.ts.map +1 -1
- package/dist/lifecycle/query.js +89 -7
- package/dist/lifecycle/replay.d.ts +10 -3
- package/dist/lifecycle/replay.d.ts.map +1 -1
- package/dist/lifecycle/replay.js +10 -6
- package/dist/lifecycle/scenario.d.ts +4 -3
- package/dist/lifecycle/scenario.d.ts.map +1 -1
- package/dist/lifecycle/snapshot-store-fake.d.ts +9 -0
- package/dist/lifecycle/snapshot-store-fake.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store-fake.js +21 -0
- package/dist/lifecycle/snapshot-store-s3.d.ts +102 -0
- package/dist/lifecycle/snapshot-store-s3.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store-s3.js +254 -0
- package/dist/lifecycle/snapshot-store.d.ts +170 -0
- package/dist/lifecycle/snapshot-store.d.ts.map +1 -0
- package/dist/lifecycle/snapshot-store.js +832 -0
- package/dist/lifecycle/snapshot.d.ts +11 -0
- package/dist/lifecycle/snapshot.d.ts.map +1 -1
- package/dist/lifecycle/snapshot.js +18 -5
- package/dist/lifecycle/type-listing.d.ts +148 -0
- package/dist/lifecycle/type-listing.d.ts.map +1 -0
- package/dist/lifecycle/type-listing.js +166 -0
- package/dist/lint/component-checks.d.ts +15 -1
- package/dist/lint/component-checks.d.ts.map +1 -1
- package/dist/lint/component-checks.js +1 -0
- package/dist/lint/presets/relaxed.json +2 -1
- package/dist/lint/presets/strict.json +2 -1
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.js +13 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.js +8 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.d.ts +33 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp008-applies-signal-only-root.js +123 -0
- package/dist/lint/rules/comp/index.d.ts +2 -1
- package/dist/lint/rules/comp/index.d.ts.map +1 -1
- package/dist/lint/rules/comp/index.js +4 -1
- package/dist/observation.d.ts +19 -2
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +18 -1
- package/dist/op/activities/activity-contracts.d.ts +1 -1
- package/dist/op/activities/activity-contracts.js +1 -1
- package/dist/op/activities/change-set.d.ts +6 -4
- package/dist/op/activities/change-set.d.ts.map +1 -1
- package/dist/op/activities/change-set.js +4 -2
- package/dist/op/activity-failure.d.ts +27 -0
- package/dist/op/activity-failure.d.ts.map +1 -1
- package/dist/op/activity-failure.js +31 -0
- package/dist/op/index.d.ts +2 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/index.js +1 -1
- package/dist/op/local-executor.d.ts +5 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-executor.js +22 -8
- package/dist/pr-loop.d.ts +92 -3
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +62 -3
- package/dist/pulumi-urn.d.ts +101 -0
- package/dist/pulumi-urn.d.ts.map +1 -0
- package/dist/pulumi-urn.js +131 -0
- package/dist/release-floors.d.ts +23 -0
- package/dist/release-floors.d.ts.map +1 -0
- package/dist/release-floors.js +22 -0
- package/dist/sensitive-key.d.ts +23 -0
- package/dist/sensitive-key.d.ts.map +1 -0
- package/dist/sensitive-key.js +31 -0
- package/dist/wave-runtime.mjs +234 -234
- package/dist/workspace/adoption-report.d.ts +53 -0
- package/dist/workspace/adoption-report.d.ts.map +1 -0
- package/dist/workspace/adoption-report.js +76 -0
- package/dist/workspace/capabilities-contract.d.ts +7 -0
- package/dist/workspace/capabilities-contract.d.ts.map +1 -1
- package/dist/workspace/capabilities-contract.js +2 -1
- package/dist/workspace/capabilities.schema.json +98 -0
- package/dist/workspace/change-set.schema.json +42 -3
- package/dist/workspace/ci-cloud-identity.d.ts +13 -1
- package/dist/workspace/ci-cloud-identity.d.ts.map +1 -1
- package/dist/workspace/ci-cloud-identity.js +30 -1
- package/dist/workspace/compose-graph.d.ts +10 -1
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/compose-graph.js +6 -1
- package/dist/workspace/conformance/index.d.ts +1 -1
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/index.js +6 -1
- package/dist/workspace/drift-cli.d.ts +81 -0
- package/dist/workspace/drift-cli.d.ts.map +1 -0
- package/dist/workspace/drift-cli.js +317 -0
- package/dist/workspace/drift.schema.json +672 -0
- package/dist/workspace/graph-cli.d.ts +2 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/graph-cli.js +3 -0
- package/dist/workspace/graph.schema.json +72 -0
- package/dist/workspace/init.d.ts +5 -1
- package/dist/workspace/init.d.ts.map +1 -1
- package/dist/workspace/init.js +55 -9
- package/dist/workspace/ledger.schema.json +1 -1
- package/dist/workspace/nested-graph.d.ts.map +1 -1
- package/dist/workspace/nested-graph.js +2 -0
- package/dist/workspace/pr-report.schema.json +76 -3
- package/dist/workspace/promote-waves.d.ts +112 -0
- package/dist/workspace/promote-waves.d.ts.map +1 -0
- package/dist/workspace/promote-waves.js +290 -0
- package/dist/workspace/promote.d.ts +84 -2
- package/dist/workspace/promote.d.ts.map +1 -1
- package/dist/workspace/promote.js +347 -61
- package/dist/workspace/reason-codes.d.ts +12 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +14 -0
- package/dist/workspace/search-contract.d.ts +3 -3
- package/dist/workspace/search-contract.d.ts.map +1 -1
- package/dist/workspace/search-contract.js +2 -0
- package/dist/workspace/search.schema.json +103 -5
- package/package.json +14 -1
- package/src/__fixtures__/drift-record/README.md +58 -0
- package/src/__fixtures__/drift-record/choudoufu-cone.ndjson +4 -0
- package/src/__fixtures__/drift-record/choudoufu-resource.ndjson +3 -0
- package/src/__fixtures__/drift-record/component-status-ledger.json +65 -0
- package/src/__fixtures__/drift-record/component-status.json +91 -0
- package/src/__fixtures__/drift-record/deep-diff.json +259 -0
- package/src/__fixtures__/drift-record/lifecycle-diff-live.json +825 -0
- package/src/__fixtures__/drift-record/live-diff.json +125 -0
- package/src/audit/discover.e2e.test.ts +14 -0
- package/src/audit/discover.ts +3 -1
- package/src/behaviour.ts +1 -1
- package/src/capabilities/templates.json +145 -0
- package/src/capabilities/templates.test.ts +212 -0
- package/src/capabilities/templates.ts +204 -0
- package/src/change-set-bundle.test.ts +83 -0
- package/src/change-set-graph.ts +80 -9
- package/src/change-set.test.ts +24 -0
- package/src/change-set.ts +77 -14
- package/src/ci-identity-targets.test.ts +23 -0
- package/src/ci-identity.ts +10 -4
- package/src/cli/commands/import-index.test.ts +117 -0
- package/src/cli/commands/import-index.ts +265 -0
- package/src/cli/commands/lint.ts +4 -2
- package/src/cli/handlers/components.test.ts +9 -0
- package/src/cli/handlers/components.ts +12 -2
- package/src/cli/handlers/fan-out.ts +17 -3
- package/src/cli/handlers/graph.test.ts +42 -0
- package/src/cli/handlers/graph.ts +26 -4
- package/src/cli/handlers/index-cloud.ts +32 -0
- package/src/cli/handlers/index-diff.test.ts +68 -0
- package/src/cli/handlers/index-diff.ts +146 -0
- package/src/cli/handlers/ledger-root-member.test.ts +161 -0
- package/src/cli/handlers/lifecycle-drift.ts +68 -0
- package/src/cli/handlers/lifecycle.test.ts +33 -11
- package/src/cli/handlers/lifecycle.ts +205 -30
- package/src/cli/handlers/misc.ts +73 -0
- package/src/cli/handlers/pr-waves-blocked.test.ts +37 -2
- package/src/cli/handlers/pr.ts +16 -3
- package/src/cli/handlers/promote.test.ts +64 -0
- package/src/cli/handlers/promote.ts +81 -6
- package/src/cli/handlers/query.ts +27 -4
- package/src/cli/handlers/run-declared-reads-cli.test.ts +187 -0
- package/src/cli/handlers/run-groups-cli.test.ts +229 -0
- package/src/cli/handlers/scenario.test.ts +13 -0
- package/src/cli/handlers/scenario.ts +8 -7
- package/src/cli/handlers/search-index.test.ts +255 -0
- package/src/cli/handlers/search-json.test.ts +1 -1
- package/src/cli/handlers/search-ownership.test.ts +194 -0
- package/src/cli/handlers/search.ts +271 -38
- package/src/cli/main.test.ts +7 -0
- package/src/cli/main.ts +56 -1
- package/src/cli/mcp/lifecycle-tools.ts +3 -2
- package/src/cli/mcp/resource-handlers.ts +4 -3
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/cli/parse-args.ts +40 -2
- package/src/cli/registry.ts +19 -1
- package/src/cloud-lister/aws.test.ts +202 -0
- package/src/cloud-lister/aws.ts +226 -0
- package/src/cloud-lister/azure.test.ts +132 -0
- package/src/cloud-lister/azure.ts +142 -0
- package/src/cloud-lister/common.ts +115 -0
- package/src/cloud-lister/credentials.ts +110 -0
- package/src/cloud-lister/fakes.ts +66 -0
- package/src/cloud-lister/gcp.test.ts +121 -0
- package/src/cloud-lister/gcp.ts +159 -0
- package/src/cloud-lister/guard.test.ts +198 -0
- package/src/cloud-lister/guard.ts +111 -0
- package/src/cloud-lister/ids.ts +54 -0
- package/src/cloud-lister/index.ts +134 -0
- package/src/cloud-lister/kubernetes.test.ts +160 -0
- package/src/cloud-lister/kubernetes.ts +284 -0
- package/src/cloud-lister/markers.ts +74 -0
- package/src/cloud-lister/mask.ts +77 -0
- package/src/cloud-lister/shape.test.ts +81 -0
- package/src/cloud-lister/sigv4.ts +70 -0
- package/src/cloud-lister/transport.ts +118 -0
- package/src/cloud-lister/types.ts +135 -0
- package/src/components/capability-plugin-loader.ts +4 -0
- package/src/components/capability-plugin.ts +10 -0
- package/src/components/capability.ts +238 -0
- package/src/components/cli-support.ts +70 -14
- package/src/components/covered-round.test.ts +166 -0
- package/src/components/covered-round.ts +293 -0
- package/src/components/declared-reads.test.ts +103 -0
- package/src/components/declared-reads.ts +134 -0
- package/src/components/deploy-units.ts +4 -0
- package/src/components/driver.ts +101 -4
- package/src/components/fan-out-run.ts +95 -15
- package/src/components/fan-out-support.ts +10 -1
- package/src/components/fan-out.ts +30 -0
- package/src/components/groups.test.ts +320 -0
- package/src/components/groups.ts +880 -0
- package/src/components/index.ts +59 -0
- package/src/components/plan-shape-conformance.ts +130 -0
- package/src/components/pr-env-run-bundle.test.ts +2 -0
- package/src/components/pr-run.test.ts +728 -4
- package/src/components/pr-run.ts +395 -55
- package/src/components/promote-rounds.ts +25 -2
- package/src/components/promote.ts +55 -5
- package/src/components/registry.test.ts +1 -1
- package/src/components/release-gate.ts +115 -30
- package/src/components/release-groups.test.ts +362 -0
- package/src/components/run-groups.ts +113 -0
- package/src/components/starter-plugin.ts +6 -0
- package/src/components/verbs/index.ts +1 -0
- package/src/components/verbs/member-outputs.test.ts +205 -0
- package/src/components/verbs/member-outputs.ts +308 -0
- package/src/components/wave-plan.ts +5 -2
- package/src/config.ts +44 -0
- package/src/deep-observation.ts +5 -23
- package/src/drift-record.test.ts +596 -0
- package/src/drift-record.ts +1206 -0
- package/src/engine-facts.guard.test.ts +111 -0
- package/src/engine-facts.test.ts +178 -0
- package/src/engine-facts.ts +154 -0
- package/src/gated-waves-bundle.test.ts +2 -0
- package/src/graph-ir-live.test.ts +92 -0
- package/src/graph-ir.ts +317 -7
- package/src/graph-refs.ts +416 -0
- package/src/graph-schema/fixtures/adopt.json +15 -0
- package/src/graph-schema/fixtures/choudoufu.engine-graph.json +169 -0
- package/src/graph-schema/fixtures/index.json +68 -0
- package/src/graph-schema/fixtures/plunge.engine-graph.json +158 -0
- package/src/graph-schema/fixtures.ts +267 -0
- package/src/graph-schema/generate.ts +263 -0
- package/src/graph-schema/graph-schema.test.ts +153 -0
- package/src/graph-schema/graph.schema.json +1387 -0
- package/src/health.schema.json +2 -1
- package/src/identity.ts +2 -0
- package/src/index.ts +2 -0
- package/src/instance-nodes.ts +288 -0
- package/src/lexicon.ts +76 -0
- package/src/lifecycle/__fixtures__/index-diff/20261026T120000Z-aaaaaaaaaaaa.json +149 -0
- package/src/lifecycle/__fixtures__/index-diff/20261026T130000Z-bbbbbbbbbbbb.json +127 -0
- package/src/lifecycle/adoption-file.test.ts +100 -0
- package/src/lifecycle/adoption-file.ts +154 -0
- package/src/lifecycle/cloud-index.test.ts +517 -0
- package/src/lifecycle/cloud-index.ts +736 -0
- package/src/lifecycle/derive-edges.test.ts +193 -0
- package/src/lifecycle/derive-edges.ts +182 -0
- package/src/lifecycle/git.ts +10 -4
- package/src/lifecycle/identity-match.test.ts +308 -0
- package/src/lifecycle/identity-match.ts +257 -0
- package/src/lifecycle/index-diff.test.ts +198 -0
- package/src/lifecycle/index-diff.ts +476 -0
- package/src/lifecycle/index-document.test.ts +64 -0
- package/src/lifecycle/index-document.ts +299 -0
- package/src/lifecycle/index-drift.test.ts +191 -0
- package/src/lifecycle/index-drift.ts +304 -0
- package/src/lifecycle/index-import.test.ts +255 -0
- package/src/lifecycle/index-import.ts +634 -0
- package/src/lifecycle/index-join.test.ts +250 -0
- package/src/lifecycle/index-join.ts +304 -0
- package/src/lifecycle/index-store-load-bearing.test.ts +187 -0
- package/src/lifecycle/index.ts +4 -0
- package/src/lifecycle/member-ledger.test.ts +25 -7
- package/src/lifecycle/observation-baseline.test.ts +72 -1
- package/src/lifecycle/observation-baseline.ts +190 -27
- package/src/lifecycle/observe.ts +6 -1
- package/src/lifecycle/query.test.ts +69 -1
- package/src/lifecycle/query.ts +103 -10
- package/src/lifecycle/replay.test.ts +9 -5
- package/src/lifecycle/replay.ts +9 -5
- package/src/lifecycle/scenario.ts +4 -3
- package/src/lifecycle/snapshot-store-fake.ts +29 -0
- package/src/lifecycle/snapshot-store-s3.ts +316 -0
- package/src/lifecycle/snapshot-store.test.ts +385 -0
- package/src/lifecycle/snapshot-store.ts +981 -0
- package/src/lifecycle/snapshot.test.ts +13 -0
- package/src/lifecycle/snapshot.ts +23 -6
- package/src/lifecycle/type-listing.test.ts +166 -0
- package/src/lifecycle/type-listing.ts +309 -0
- package/src/lint/component-checks.ts +17 -1
- package/src/lint/config.test.ts +3 -0
- package/src/lint/presets/relaxed.json +2 -1
- package/src/lint/presets/strict.json +2 -1
- package/src/lint/rules/__fixtures__/comp/comp008/fail/dns.component.ts +15 -0
- package/src/lint/rules/__fixtures__/comp/comp008/pass/dns.component.ts +10 -0
- package/src/lint/rules/comp/comp.test.ts +2 -1
- package/src/lint/rules/comp/comp008-applies-signal-only-root.ts +121 -0
- package/src/lint/rules/comp/comp008.test.ts +77 -0
- package/src/lint/rules/comp/index.ts +4 -1
- package/src/observation-edges.test.ts +33 -0
- package/src/observation.ts +36 -1
- package/src/op/activities/activity-contracts.ts +1 -1
- package/src/op/activities/change-set.ts +8 -5
- package/src/op/activity-failure.ts +36 -0
- package/src/op/index.ts +2 -1
- package/src/op/local-executor.test.ts +80 -0
- package/src/op/local-executor.ts +27 -9
- package/src/pr-loop-bundle.test.ts +5 -2
- package/src/pr-loop.test.ts +57 -1
- package/src/pr-loop.ts +154 -6
- package/src/pulumi-urn.ts +151 -0
- package/src/release-floors.ts +22 -0
- package/src/sensitive-key.ts +34 -0
- package/src/workspace/adoption-report.test.ts +61 -0
- package/src/workspace/adoption-report.ts +103 -0
- package/src/workspace/capabilities-contract.test.ts +4 -0
- package/src/workspace/capabilities-contract.ts +9 -1
- package/src/workspace/capabilities.schema.json +98 -0
- package/src/workspace/change-set.schema.json +42 -3
- package/src/workspace/ci-cloud-identity.ts +31 -1
- package/src/workspace/compose-graph.test.ts +12 -0
- package/src/workspace/compose-graph.ts +12 -1
- package/src/workspace/conformance/conformance.e2e.test.ts +2 -1
- package/src/workspace/conformance/index.ts +6 -1
- package/src/workspace/drift-cli.test.ts +65 -0
- package/src/workspace/drift-cli.ts +365 -0
- package/src/workspace/drift.schema.json +672 -0
- package/src/workspace/graph-cli.ts +5 -0
- package/src/workspace/graph.schema.json +72 -0
- package/src/workspace/init.test.ts +38 -1
- package/src/workspace/init.ts +50 -8
- package/src/workspace/intent-gaps.test.ts +18 -2
- package/src/workspace/ledger.schema.json +1 -1
- package/src/workspace/nested-graph.ts +1 -0
- package/src/workspace/pr-report.schema.json +76 -3
- package/src/workspace/promote-waves.test.ts +296 -0
- package/src/workspace/promote-waves.ts +340 -0
- package/src/workspace/promote.test.ts +158 -4
- package/src/workspace/promote.ts +398 -57
- package/src/workspace/reason-codes.test.ts +4 -1
- package/src/workspace/reason-codes.ts +14 -0
- package/src/workspace/search-contract.ts +2 -0
- package/src/workspace/search.schema.json +103 -5
package/src/cli/main.ts
CHANGED
|
@@ -173,7 +173,9 @@ Commands:
|
|
|
173
173
|
terms, ->* / ->{1,3} for depth, ->[via=attr] / [to=attr]
|
|
174
174
|
by attribute; --live or --snapshot <ref> (also --at
|
|
175
175
|
<ref>) with --env <name> reads the estate or a
|
|
176
|
-
recorded snapshot; --
|
|
176
|
+
recorded snapshot; --index <scope key>[@<version>]
|
|
177
|
+
answers from an index version, joined to the
|
|
178
|
+
declared rows, or alone with no project; --show <attr>,
|
|
177
179
|
--count-by kind|module|attr:<name>, --explain prints
|
|
178
180
|
paths, --json, --check-live,
|
|
179
181
|
--check-snapshot, --fail-on-drift; cap:<name> and
|
|
@@ -191,6 +193,16 @@ Commands:
|
|
|
191
193
|
--where <field><op><value> (= != < <= > >= ~,
|
|
192
194
|
repeatable), --since <time|7d>, --at <rev> of
|
|
193
195
|
chant/lifecycle, --member <name>, --json
|
|
196
|
+
index <substrate> Read one aws account, azure subscription, gcp project
|
|
197
|
+
or kubernetes cluster through its inventory API, type
|
|
198
|
+
it, derive its edges and write one index version to
|
|
199
|
+
the index store. Read-only: refuses action flags.
|
|
200
|
+
--account|--subscription|--project|--cluster, --regions,
|
|
201
|
+
--types, --tag k=v, --endpoint, --store <spec>, --json
|
|
202
|
+
(chant index --help for the rest)
|
|
203
|
+
index diff <a> [<b>] What changed between two index versions of one scope:
|
|
204
|
+
<scopeKey>/<version>, or <scopeKey> for its last two.
|
|
205
|
+
--store <spec>, --json (chant index diff --help)
|
|
194
206
|
generate Generate typed code from sources chant.config declares
|
|
195
207
|
(k8s.crds, helm.charts) into src/generated/<lexicon>/
|
|
196
208
|
(codegen.outDir); --check exits 1 when the committed
|
|
@@ -624,6 +636,12 @@ Workspace (level 1, #2524):
|
|
|
624
636
|
choudoufu runs live-check and the adoption report;
|
|
625
637
|
choudoufu or other to chant runs chant import), staged
|
|
626
638
|
in a worktree and gated on the patch digest like upgrade
|
|
639
|
+
workspace promote --all [--state-dir <dir>] [--state <member>=<tfstate>]... [--canary <member>] [--wave-size <n>] [--dry-run] [--json]
|
|
640
|
+
Adopt every terraform member into choudoufu in waves:
|
|
641
|
+
the canary first (default the first member), then
|
|
642
|
+
--wave-size roots a wave (default 5), one gate per
|
|
643
|
+
root bound to its live-import report digest. A wave
|
|
644
|
+
that does not land stops the later ones (#4461)
|
|
627
645
|
workspace ls [dir] List the declaration's members and example groups.
|
|
628
646
|
A member that can't be read is listed with a reason
|
|
629
647
|
code and still exits 0. --at <rev> reads a commit's
|
|
@@ -981,6 +999,15 @@ Workspace (level 1, #2524):
|
|
|
981
999
|
--no-cache reads every member
|
|
982
1000
|
--capability-view: each member's chant adds its
|
|
983
1001
|
capability view, mapped by its own lexicons
|
|
1002
|
+
workspace drift --member <name> [--read <state|plan|refresh|live-read|ownership>] [--resource <addr>] [--env <name>] [--stream] [-o <file>]
|
|
1003
|
+
One member's drift, read by its own engine: a chant
|
|
1004
|
+
member through lifecycle diff --live (needs --env), a
|
|
1005
|
+
terraform member through its state or a plan, a
|
|
1006
|
+
choudoufu member through live-plan (and a plan for
|
|
1007
|
+
--read plan), one resource through choudoufu
|
|
1008
|
+
live-plan -resource. One drift document, or with
|
|
1009
|
+
--stream the NDJSON stream (drift-start, records,
|
|
1010
|
+
drift-settle)
|
|
984
1011
|
workspace search "<query>" [--member <name>] [--env <name>] [--snapshot <ref> | --live] [--at <rev>] [--explain] [--count-by ...] [--json]
|
|
985
1012
|
chant search in every chant member, each under its own
|
|
986
1013
|
chant, as one read-contract document: ids are
|
|
@@ -1038,6 +1065,8 @@ Lifecycle (alias: lc):
|
|
|
1038
1065
|
(lexicons with a deep reader also report
|
|
1039
1066
|
property-level drift; --update-baseline records
|
|
1040
1067
|
what it reports as accepted so it stops alerting)
|
|
1068
|
+
--index <ref>: compare source with an index version
|
|
1069
|
+
in the store, no deploy and no cloud read (#4526)
|
|
1041
1070
|
lifecycle plan <env> Typed change set (create/update/delete/adopt) vs live
|
|
1042
1071
|
--deep: also report properties declared
|
|
1043
1072
|
heldElsewhere(). Never changes what the plan
|
|
@@ -1050,6 +1079,9 @@ Lifecycle (alias: lc):
|
|
|
1050
1079
|
drift: ECS running vs desired, Route 53 health
|
|
1051
1080
|
checks, Container Apps revisions, Cloud Run Ready.
|
|
1052
1081
|
A failed read is "not read", never unhealthy (--json)
|
|
1082
|
+
lifecycle drift Each lexicon's own drift read, as drift-record
|
|
1083
|
+
NDJSON (--member, --read, --resource); what
|
|
1084
|
+
workspace drift runs in a member's reader project
|
|
1053
1085
|
lifecycle whoami <env> Who chant would act as in each configured lexicon,
|
|
1054
1086
|
and what that principal is scoped to — read-only,
|
|
1055
1087
|
before anything acts (--json, --strict)
|
|
@@ -1354,6 +1386,7 @@ Examples:
|
|
|
1354
1386
|
chant import manifest.yaml --lexicon k8s --output ./infra/
|
|
1355
1387
|
chant import dash.json --lexicon grafana --parser-option acceptLossyV1
|
|
1356
1388
|
chant import --from prod --name my-bucket --output src/
|
|
1389
|
+
chant import --index index.json --type AWS::S3::Bucket --output src/imported/
|
|
1357
1390
|
chant lint ./infra/
|
|
1358
1391
|
chant lint ./infra/ --format sarif
|
|
1359
1392
|
chant lint ./infra/ --watch
|
|
@@ -1564,6 +1597,10 @@ export const commandRegistry: CommandDef[] = [
|
|
|
1564
1597
|
// #4297 — SQL over the snapshots, runs, gates, deploys and releases on chant/lifecycle. Imported on first use.
|
|
1565
1598
|
{ name: "query", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/query")).runQueryCommand(ctx) },
|
|
1566
1599
|
{ name: "ledger", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/ledger")).runLedgerCommand(ctx) },
|
|
1600
|
+
// chant#4532 — a read-only cloud index. main() hands `index`'s raw argv to
|
|
1601
|
+
// its own parser before parseArgs; this entry answers "is it a verb" and
|
|
1602
|
+
// runs the words a caller already parsed (substrate, --json, --help).
|
|
1603
|
+
{ name: "index", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/index-cloud")).runIndexCommand(ctx) },
|
|
1567
1604
|
// chant#2591 — `import --agents` and `audit` read chant.config statically
|
|
1568
1605
|
// and never evaluate it (chant#2589 for audit, which audits code it must not run).
|
|
1569
1606
|
{ name: "import", handler: runImport, runsNoConfig: (args) => args.agents === true },
|
|
@@ -1702,6 +1739,7 @@ export const commandRegistry: CommandDef[] = [
|
|
|
1702
1739
|
{ name: "workspace run", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/workspace-run")).runWorkspaceRun(ctx) },
|
|
1703
1740
|
// #2554 — a release train: one release of every chant member, pinned in the workspace ledger.
|
|
1704
1741
|
{ name: "workspace train", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/release-train")).runWorkspaceTrain(ctx) },
|
|
1742
|
+
{ name: "workspace drift", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/drift-cli")).runWorkspaceDrift(ctx) },
|
|
1705
1743
|
{ name: "workspace search", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/search-cli")).runWorkspaceSearch(ctx) },
|
|
1706
1744
|
// Each unit decides for itself whether its config is loaded (runCommandInProcess).
|
|
1707
1745
|
{ name: "workspace member-run", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/member-run")).runWorkspaceMemberRun(ctx, runCommandInProcess) },
|
|
@@ -1730,6 +1768,7 @@ export const commandRegistry: CommandDef[] = [
|
|
|
1730
1768
|
{ name: "lifecycle rollback", handler: runLifecycleRollback },
|
|
1731
1769
|
{ name: "lifecycle plan", requiresPlugins: true, handler: runLifecyclePlan },
|
|
1732
1770
|
{ name: "lifecycle affected", requiresPlugins: true, handler: runLifecycleAffected },
|
|
1771
|
+
{ name: "lifecycle drift", requiresPlugins: true, handler: async (ctx) => (await import("./handlers/lifecycle-drift")).runLifecycleDrift(ctx) },
|
|
1733
1772
|
{ name: "lifecycle whoami", requiresPlugins: true, handler: runLifecycleWhoami },
|
|
1734
1773
|
// #4177 — runtime health, separate from drift. Imported on first use.
|
|
1735
1774
|
{ name: "lifecycle health", requiresPlugins: true, handler: async (ctx) => (await import("./handlers/lifecycle-health")).runLifecycleHealth(ctx) },
|
|
@@ -1790,6 +1829,22 @@ async function main(): Promise<void> {
|
|
|
1790
1829
|
installCompiledCli();
|
|
1791
1830
|
const rawArgv = process.argv.slice(2);
|
|
1792
1831
|
|
|
1832
|
+
// chant#4532 — `chant index <substrate>` takes its own flags (--account,
|
|
1833
|
+
// --regions, --endpoint, ...) that core's one flat parser does not know, and
|
|
1834
|
+
// must refuse an action flag (--apply, --yes, ...) that the parser would
|
|
1835
|
+
// accept. So its argv goes to its own parser, before parseArgs.
|
|
1836
|
+
if (rawArgv[0] === "index" && rawArgv[1] === "diff") {
|
|
1837
|
+
// #4533 — `chant index diff <a> [<b>]`: two stored versions of one scope.
|
|
1838
|
+
const { runIndexDiff } = await import("./handlers/index-diff");
|
|
1839
|
+
await flushAndExit(await runIndexDiff(rawArgv.slice(2)));
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1842
|
+
if (rawArgv[0] === "index") {
|
|
1843
|
+
const { runCloudIndex } = await import("../lifecycle/cloud-index");
|
|
1844
|
+
await flushAndExit(await runCloudIndex(rawArgv.slice(1)));
|
|
1845
|
+
return;
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1793
1848
|
let args: ParsedArgs;
|
|
1794
1849
|
try {
|
|
1795
1850
|
args = parseArgs(rawArgv);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
2
|
import type { LexiconPlugin } from "../../lexicon";
|
|
3
3
|
import type { ToolDefinition, ToolHandler } from "./types";
|
|
4
|
-
import {
|
|
4
|
+
import { resolveSnapshotStore } from "../../lifecycle/snapshot-store";
|
|
5
5
|
import { build } from "../../build";
|
|
6
6
|
import { computeBuildDigest, diffDigests } from "../../lifecycle/digest";
|
|
7
7
|
import { takeSnapshot } from "../../lifecycle/snapshot";
|
|
@@ -71,8 +71,9 @@ export function createDiffTool(plugins: LexiconPlugin[]): ToolRegistration {
|
|
|
71
71
|
const currentDigest = computeBuildDigest(buildResult);
|
|
72
72
|
const lexicons = lexiconFilter ? [lexiconFilter] : buildResult.manifest.lexicons;
|
|
73
73
|
const results: Record<string, unknown> = {};
|
|
74
|
+
const store = await resolveSnapshotStore();
|
|
74
75
|
for (const lex of lexicons) {
|
|
75
|
-
const content = await
|
|
76
|
+
const content = await store.readLatest(env, lex);
|
|
76
77
|
let previousDigest = undefined;
|
|
77
78
|
if (content) {
|
|
78
79
|
const snapshot: LifecycleSnapshot = JSON.parse(content);
|
|
@@ -4,7 +4,7 @@ import type { ResourceDefinition } from "./types";
|
|
|
4
4
|
import type { LexiconPlugin } from "../../lexicon";
|
|
5
5
|
import { collectComposites } from "./tools/composites";
|
|
6
6
|
import { getContext } from "./resources/context";
|
|
7
|
-
import {
|
|
7
|
+
import { readEnvironmentSnapshotsFrom, resolveSnapshotStore } from "../../lifecycle/snapshot-store";
|
|
8
8
|
import { discoverOps } from "../../op/discover";
|
|
9
9
|
import { createLocalOpRuntime } from "../../op/runtimes/local";
|
|
10
10
|
import { loadOkfBundle } from "../../okf-read";
|
|
@@ -224,14 +224,15 @@ export async function handleResourcesRead(
|
|
|
224
224
|
const environment = parts[0];
|
|
225
225
|
const lexicon = parts[1];
|
|
226
226
|
|
|
227
|
+
const store = await resolveSnapshotStore();
|
|
227
228
|
if (lexicon) {
|
|
228
|
-
const content = await
|
|
229
|
+
const content = await store.readLatest(environment, lexicon);
|
|
229
230
|
if (!content) throw new Error(`No snapshot found for ${environment}/${lexicon}`);
|
|
230
231
|
return {
|
|
231
232
|
contents: [{ uri, mimeType: "application/json", text: content }],
|
|
232
233
|
};
|
|
233
234
|
} else {
|
|
234
|
-
const snapshots = await
|
|
235
|
+
const snapshots = await readEnvironmentSnapshotsFrom(store, environment);
|
|
235
236
|
const result: Record<string, unknown> = {};
|
|
236
237
|
for (const [lex, content] of snapshots) {
|
|
237
238
|
result[lex] = JSON.parse(content);
|
|
@@ -127,7 +127,7 @@ export const workspaceReadTools: ToolDefinition[] = [
|
|
|
127
127
|
name: "workspace-search",
|
|
128
128
|
description:
|
|
129
129
|
"Answer an estate question over every chant member of the workspace with a few rows instead of the whole graph: chant workspace search <query> --json (search.schema.json, #4374). Returns that document unchanged. Each member is searched under its own chant and alone, ids are <member>/<id> as workspace-graph names the same nodes, and a member that can't be searched is listed with a reason code, never as zero matches. " +
|
|
130
|
-
"The query is space-separated terms that must all match: a bare word (substring of id, kind or attributes), kind:<substr> (a Terraform resource matches its type, kind:aws_instance), attr:<name>=<value>, tag:<key>=<value>, and edge terms ->X (this node references a node matching X) and <-X (referenced by one); ->*X is any depth, ->{2}X or ->{1,3}X a number of hops, ->[via=attr]X and ->[to=attr]X pick the edge by attribute, and !term negates. " +
|
|
130
|
+
"The query is space-separated terms that must all match: a bare word (substring of id, kind or attributes), kind:<substr> (a Terraform resource matches its type, kind:aws_instance), attr:<name>=<value>, tag:<key>=<value>, id:<cloud id> (exact, over physical and cloud ids), and edge terms ->X (this node references a node matching X) and <-X (referenced by one); ->*X is any depth, ->{2}X or ->{1,3}X a number of hops, ->[via=attr]X and ->[to=attr]X pick the edge by attribute, and !term negates. " +
|
|
131
131
|
"at is the git revision of the source; snapshot (with env) answers from a recorded lifecycle snapshot such as latest. They are two different times, and at refuses a snapshot ref.",
|
|
132
132
|
inputSchema: {
|
|
133
133
|
type: "object",
|
package/src/cli/parse-args.ts
CHANGED
|
@@ -24,6 +24,7 @@ const BOOLEAN_FLAGS = new Set([
|
|
|
24
24
|
"--agents",
|
|
25
25
|
"--agent",
|
|
26
26
|
"--all-projects",
|
|
27
|
+
"--all",
|
|
27
28
|
"--force",
|
|
28
29
|
"--fix",
|
|
29
30
|
"--watch",
|
|
@@ -78,6 +79,7 @@ const BOOLEAN_FLAGS = new Set([
|
|
|
78
79
|
"--no-require-review",
|
|
79
80
|
"--expire",
|
|
80
81
|
"--check-live",
|
|
82
|
+
"--stream",
|
|
81
83
|
"--check-snapshot",
|
|
82
84
|
"--fail-on-drift",
|
|
83
85
|
"--durable-requests",
|
|
@@ -247,6 +249,11 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
247
249
|
const v = args[++i];
|
|
248
250
|
if (!v || v.startsWith("-")) throw new Error("--parser-option needs key or key=value: --parser-option acceptLossyV1");
|
|
249
251
|
(result.parserOption ??= []).push(v);
|
|
252
|
+
} else if (arg === "--tag") {
|
|
253
|
+
// `chant import --index <ref> --tag key=value` (#4524), repeatable: every tag must match.
|
|
254
|
+
const v = args[++i];
|
|
255
|
+
if (!v || v.startsWith("-") || !v.includes("=")) throw new Error("--tag needs key=value: --tag team=payments");
|
|
256
|
+
(result.selectTags ??= []).push(v);
|
|
250
257
|
} else if (arg === "--type") {
|
|
251
258
|
result.selectType = args[++i];
|
|
252
259
|
} else if (arg === "--name") {
|
|
@@ -266,6 +273,20 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
266
273
|
result.skipUndeclarable = true;
|
|
267
274
|
} else if (arg === "--state") {
|
|
268
275
|
result.statePath = args[++i];
|
|
276
|
+
// `chant workspace promote --all --state <member>=<path>` (#4461), repeatable.
|
|
277
|
+
if (result.statePath !== undefined) (result.statePaths ??= []).push(result.statePath);
|
|
278
|
+
} else if (arg === "--state-dir") {
|
|
279
|
+
// `chant workspace promote --all --state-dir <dir>` (#4461): <dir>/<member>.tfstate.
|
|
280
|
+
result.stateDir = args[++i];
|
|
281
|
+
if (!result.stateDir || result.stateDir.startsWith("-")) throw new Error("--state-dir needs a directory: --state-dir <dir>");
|
|
282
|
+
} else if (arg === "--wave-size") {
|
|
283
|
+
const raw = args[++i];
|
|
284
|
+
const size = Number(raw);
|
|
285
|
+
if (!Number.isInteger(size) || size < 1) throw new Error(`--wave-size needs a whole number from 1: got "${raw ?? ""}"`);
|
|
286
|
+
result.waveSize = size;
|
|
287
|
+
} else if (arg === "--all") {
|
|
288
|
+
// `chant workspace promote --all` (#4461): every terraform member.
|
|
289
|
+
result.all = true;
|
|
269
290
|
} else if (arg === "--select") {
|
|
270
291
|
result.selectAddress = args[++i];
|
|
271
292
|
} else if (arg === "--live-name") {
|
|
@@ -980,9 +1001,14 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
980
1001
|
result.tags = args[++i];
|
|
981
1002
|
if (!result.tags || result.tags.startsWith("-")) throw new Error("--tags needs a tag glob: --tags 'v*'");
|
|
982
1003
|
} else if (arg === "--index") {
|
|
983
|
-
// #2551 — `chant workspace adopt-lineage --index <file
|
|
1004
|
+
// #2551 — `chant workspace adopt-lineage --index <file>`; #4525 — `chant search --index <ref>`;
|
|
1005
|
+
// #4526 — `chant lifecycle diff <env> --index <ref>`.
|
|
984
1006
|
result.index = args[++i];
|
|
985
|
-
if (!result.index || result.index.startsWith("-")) throw new Error("--index needs a
|
|
1007
|
+
if (!result.index || result.index.startsWith("-")) throw new Error("--index needs a value: --index <file> for workspace adopt-lineage, --index <scope key>[@<version>] for search and lifecycle diff");
|
|
1008
|
+
} else if (arg === "--adopt-out") {
|
|
1009
|
+
// #4536 — `chant import --index <ref> --adopt-out <file>`: write the adoption file (`adopt: v1`) for what was imported.
|
|
1010
|
+
result.adoptOut = args[++i];
|
|
1011
|
+
if (!result.adoptOut || result.adoptOut.startsWith("-")) throw new Error("--adopt-out needs a file: --adopt-out <file>");
|
|
986
1012
|
} else if (arg === "--remove") {
|
|
987
1013
|
// #2552 — `chant workspace import --remove` removes the export member instead of writing it again.
|
|
988
1014
|
result.remove = true;
|
|
@@ -1024,6 +1050,18 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
1024
1050
|
const value = args[++i];
|
|
1025
1051
|
if (value === undefined || value.startsWith("--")) throw new Error("--where needs a clause: --where <field><op><value>");
|
|
1026
1052
|
result.where = [...(result.where ?? []), value];
|
|
1053
|
+
} else if (arg === "--read") {
|
|
1054
|
+
// behold#995 - `chant workspace drift --read <read>`: which read the member's engine answers with.
|
|
1055
|
+
const value = args[++i];
|
|
1056
|
+
if (!value || value.startsWith("-")) throw new Error("--read needs a read: --read <state|plan|refresh|live-read|ownership>");
|
|
1057
|
+
result.driftRead = value;
|
|
1058
|
+
} else if (arg === "--stream") {
|
|
1059
|
+
result.stream = true;
|
|
1060
|
+
} else if (arg === "--resource") {
|
|
1061
|
+
// behold#995 - `chant workspace drift --resource <addr>`: one resource's drift.
|
|
1062
|
+
const value = args[++i];
|
|
1063
|
+
if (!value || value.startsWith("--")) throw new Error("--resource needs an address: --resource <addr>");
|
|
1064
|
+
result.resource = value;
|
|
1027
1065
|
} else if (arg === "--since") {
|
|
1028
1066
|
result.since = args[++i];
|
|
1029
1067
|
} else if (arg === "--limit") {
|
package/src/cli/registry.ts
CHANGED
|
@@ -91,6 +91,14 @@ export interface ParsedArgs {
|
|
|
91
91
|
parserOption?: string[];
|
|
92
92
|
/** `chant carve advise --state <path>` — opt-in .tfstate for accurate instance counts */
|
|
93
93
|
statePath?: string;
|
|
94
|
+
/** Every `--state` value in order (#4461): `chant workspace promote --all --state <member>=<path>`, repeatable. */
|
|
95
|
+
statePaths?: string[];
|
|
96
|
+
/** `chant workspace promote --all --state-dir <dir>` (#4461): a member's state is `<dir>/<member>.tfstate`. */
|
|
97
|
+
stateDir?: string;
|
|
98
|
+
/** `chant workspace promote --all --wave-size <n>` (#4461): roots per wave after the canary. */
|
|
99
|
+
waveSize?: number;
|
|
100
|
+
/** `chant workspace promote --all` (#4461): promote every terraform member, in waves. */
|
|
101
|
+
all?: boolean;
|
|
94
102
|
/** `chant carve emit --select <tf-address>` — the Terraform resource to carve */
|
|
95
103
|
selectAddress?: string;
|
|
96
104
|
/** `chant carve emit --live-name <logicalId>` — CFN logical ID for live adoption */
|
|
@@ -127,6 +135,8 @@ export interface ParsedArgs {
|
|
|
127
135
|
selectType?: string;
|
|
128
136
|
/** `chant import --name <name>` selector */
|
|
129
137
|
selectName?: string;
|
|
138
|
+
/** `chant import --index <ref> --tag key=value` (#4524), repeatable */
|
|
139
|
+
selectTags?: string[];
|
|
130
140
|
/** `chant import --owned` — restrict live import to chant-owned resources */
|
|
131
141
|
owned?: boolean;
|
|
132
142
|
/**
|
|
@@ -157,7 +167,9 @@ export interface ParsedArgs {
|
|
|
157
167
|
source?: string;
|
|
158
168
|
/** `chant workspace adopt-lineage --tags <glob>` and `hash-index --tags` (#2551): the tags to compare. */
|
|
159
169
|
tags?: string;
|
|
160
|
-
/** `chant workspace adopt-lineage --index <file>` (#2551): a cached hash index. */
|
|
170
|
+
/** `chant workspace adopt-lineage --index <file>` (#2551): a cached hash index. `chant search --index <ref>` (#4525) and `chant lifecycle diff <env> --index <ref>` (#4526): an index version. */
|
|
171
|
+
/** `chant import --index <ref> --adopt-out <file>` (#4536): where to write the adoption file. */
|
|
172
|
+
adoptOut?: string;
|
|
161
173
|
index?: string;
|
|
162
174
|
/** `chant workspace versions --available` (#2551): list each git template's version tags. */
|
|
163
175
|
available?: boolean;
|
|
@@ -496,6 +508,12 @@ export interface ParsedArgs {
|
|
|
496
508
|
store?: "tree" | "ledger";
|
|
497
509
|
/** `chant workspace points answer <id> --answer <value>` (#2739): the people's answer. */
|
|
498
510
|
answer?: string;
|
|
511
|
+
/** `chant workspace drift --read <state|plan|refresh|live-read|ownership>` and `chant lifecycle drift --read` (behold#995): the read to ask the member's engine for. Unset, the member kind's default read. */
|
|
512
|
+
driftRead?: string;
|
|
513
|
+
/** `chant workspace drift --stream` (behold#995): print the drift stream (drift-start, records, drift-settle) as NDJSON instead of one document. */
|
|
514
|
+
stream?: boolean;
|
|
515
|
+
/** `chant workspace drift --resource <addr>` and `chant lifecycle drift --resource` (behold#995): read one resource, through `choudoufu live-plan -resource` on a choudoufu member. */
|
|
516
|
+
resource?: string;
|
|
499
517
|
/** `chant workspace graph --no-cache` (#2876): read every member, bypassing the per-member cache. */
|
|
500
518
|
noCache?: boolean;
|
|
501
519
|
/** `chant workspace graph --composites` (#2662): print each composite instance with the components that can deploy it. */
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* behold#1029: the AWS lister against a fake Cloud Control. Response shapes
|
|
3
|
+
* follow the pinned floci's CloudControlJsonHandler (source c688f52ee):
|
|
4
|
+
* `{ TypeName, ResourceDescriptions: [{ Identifier, Properties }] }`, with
|
|
5
|
+
* `Properties` a JSON string.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, expect, it } from "vitest";
|
|
8
|
+
import { listCloud } from "./index";
|
|
9
|
+
import { ListerConfigError } from "./credentials";
|
|
10
|
+
import { MASKED } from "./mask";
|
|
11
|
+
import { signV4 } from "./sigv4";
|
|
12
|
+
import { fakeFetcher, json, refusingChains, steppingClock } from "./fakes";
|
|
13
|
+
import type { WireCall } from "./guard";
|
|
14
|
+
|
|
15
|
+
const ENDPOINT = "http://localhost:4566";
|
|
16
|
+
const CREDS = { accessKeyId: "test", secretAccessKey: "test" };
|
|
17
|
+
|
|
18
|
+
function target() {
|
|
19
|
+
return { substrate: "aws" as const, aws: { endpoint: ENDPOINT, credentials: CREDS } };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function typeOf(call: WireCall): { TypeName: string; NextToken?: string } {
|
|
23
|
+
return JSON.parse(call.body ?? "{}");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
describe("signV4", () => {
|
|
27
|
+
// AWS's published SigV4 test suite, case get-vanilla.
|
|
28
|
+
it("matches the get-vanilla known answer", () => {
|
|
29
|
+
const headers = signV4({
|
|
30
|
+
method: "GET",
|
|
31
|
+
url: "https://example.amazonaws.com/",
|
|
32
|
+
headers: {},
|
|
33
|
+
body: "",
|
|
34
|
+
region: "us-east-1",
|
|
35
|
+
service: "service",
|
|
36
|
+
credentials: { accessKeyId: "AKIDEXAMPLE", secretAccessKey: "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" },
|
|
37
|
+
now: new Date("2015-08-30T12:36:00Z"),
|
|
38
|
+
});
|
|
39
|
+
expect(headers.authorization).toBe(
|
|
40
|
+
"AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31",
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe("listing aws", () => {
|
|
46
|
+
it("lists each type per region, pages, and fills the listing-result shape", async () => {
|
|
47
|
+
const fake = fakeFetcher((call) => {
|
|
48
|
+
const { TypeName, NextToken } = typeOf(call);
|
|
49
|
+
if (TypeName === "AWS::S3::Bucket" && !NextToken) {
|
|
50
|
+
return json(200, {
|
|
51
|
+
TypeName,
|
|
52
|
+
ResourceDescriptions: [
|
|
53
|
+
{ Identifier: "web-assets", Properties: JSON.stringify({ BucketName: "web-assets", Arn: "arn:aws:s3:::web-assets", Tags: [{ Key: "tofu-estate", Value: "web" }, { Key: "tofu-address", Value: "aws_s3_bucket.assets" }] }) },
|
|
54
|
+
],
|
|
55
|
+
NextToken: "page2",
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (TypeName === "AWS::S3::Bucket" && NextToken === "page2") {
|
|
59
|
+
return json(200, { TypeName, ResourceDescriptions: [{ Identifier: "logs", Properties: JSON.stringify({ BucketName: "logs" }) }] });
|
|
60
|
+
}
|
|
61
|
+
if (TypeName === "AWS::RDS::DBInstance") {
|
|
62
|
+
return json(200, {
|
|
63
|
+
TypeName,
|
|
64
|
+
ResourceDescriptions: [{ Identifier: "db1", Properties: JSON.stringify({ DBInstanceIdentifier: "db1", MasterUserPassword: "hunter2", Tags: [{ Key: "api-token", Value: "abc" }] }) }],
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return undefined;
|
|
68
|
+
});
|
|
69
|
+
const result = await listCloud(
|
|
70
|
+
{ substrate: "aws", scopeId: "000000000000", locations: ["us-east-1"], types: ["AWS::S3::Bucket", "AWS::RDS::DBInstance"] },
|
|
71
|
+
target(),
|
|
72
|
+
{ fetcher: fake.fetcher, chains: refusingChains(), now: steppingClock(), retryDelays: [], version: "0.30.2" },
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
expect(result.listing).toBe("v1");
|
|
76
|
+
expect(result.source).toEqual({ name: "chant-lister", version: "0.30.2" });
|
|
77
|
+
expect(result.scope.types).toEqual(["AWS::RDS::DBInstance", "AWS::S3::Bucket"]);
|
|
78
|
+
expect(fake.calls.every((c) => c.url === `${ENDPOINT}/`)).toBe(true);
|
|
79
|
+
expect(fake.calls[0].headers.authorization).toMatch(/^AWS4-HMAC-SHA256 Credential=test\/\d{8}\/us-east-1\/cloudcontrolapi\/aws4_request/);
|
|
80
|
+
expect(fake.calls[0].headers["x-amz-target"]).toBe("CloudApiService.ListResources");
|
|
81
|
+
|
|
82
|
+
const bucket = result.resources.find((r) => r.nativeId === "web-assets")!;
|
|
83
|
+
expect(bucket.id).toBe("aws/000000000000/us-east-1/AWS::S3::Bucket/web-assets");
|
|
84
|
+
expect(bucket.listedType).toBe("AWS::S3::Bucket");
|
|
85
|
+
expect(bucket.location).toBe("us-east-1");
|
|
86
|
+
expect(bucket.cloudIds).toEqual([
|
|
87
|
+
{ kind: "arn", value: "arn:aws:s3:::web-assets" },
|
|
88
|
+
{ kind: "import-id", value: "web-assets" },
|
|
89
|
+
]);
|
|
90
|
+
expect(bucket.tags).toEqual({ "tofu-estate": "web", "tofu-address": "aws_s3_bucket.assets" });
|
|
91
|
+
expect(bucket.facts).toEqual({
|
|
92
|
+
markers: { owner: "web", address: "aws_s3_bucket.assets", encoding: "escaped", source: "live" },
|
|
93
|
+
cloudIds: bucket.cloudIds,
|
|
94
|
+
observedAt: bucket.observedAt,
|
|
95
|
+
});
|
|
96
|
+
expect(Object.keys(bucket.facts).sort()).toEqual(["cloudIds", "markers", "observedAt"]);
|
|
97
|
+
expect(result.resources.map((r) => r.nativeId)).toContain("logs");
|
|
98
|
+
|
|
99
|
+
const db = result.resources.find((r) => r.nativeId === "db1")!;
|
|
100
|
+
expect(db.properties.MasterUserPassword).toBe(MASKED);
|
|
101
|
+
expect(db.tags["api-token"]).toBe(MASKED);
|
|
102
|
+
expect(JSON.stringify(result)).not.toContain("hunter2");
|
|
103
|
+
expect(JSON.stringify(result)).not.toContain('"abc"');
|
|
104
|
+
|
|
105
|
+
expect(result.coverage).toEqual([
|
|
106
|
+
{ listedType: "AWS::RDS::DBInstance", location: "us-east-1", verdict: "listed" },
|
|
107
|
+
{ listedType: "AWS::S3::Bucket", location: "us-east-1", verdict: "listed" },
|
|
108
|
+
]);
|
|
109
|
+
expect(result.notes).toEqual([]);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("lists a global type once, as location global", async () => {
|
|
113
|
+
const fake = fakeFetcher(() => json(200, { ResourceDescriptions: [{ Identifier: "app-role", Properties: JSON.stringify({ RoleName: "app-role", Arn: "arn:aws:iam::000000000000:role/app-role" }) }] }));
|
|
114
|
+
const result = await listCloud(
|
|
115
|
+
{ substrate: "aws", scopeId: "000000000000", locations: ["us-east-1", "eu-west-1"], types: ["AWS::IAM::Role"] },
|
|
116
|
+
target(),
|
|
117
|
+
{ fetcher: fake.fetcher, chains: refusingChains(), now: steppingClock(), retryDelays: [] },
|
|
118
|
+
);
|
|
119
|
+
expect(fake.calls.length).toBe(1);
|
|
120
|
+
expect(result.resources[0].id).toBe("aws/000000000000/global/AWS::IAM::Role/app-role");
|
|
121
|
+
expect(result.coverage).toEqual([{ listedType: "AWS::IAM::Role", location: "global", verdict: "listed" }]);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("puts a type it cannot list in the notes, with its reason", async () => {
|
|
125
|
+
const fake = fakeFetcher((call) => {
|
|
126
|
+
const { TypeName } = typeOf(call);
|
|
127
|
+
if (TypeName === "AWS::Foo::Bar") return json(400, { __type: "com.amazon.cloudapiservice#UnsupportedActionException", message: "Resource type AWS::Foo::Bar does not support LIST action" });
|
|
128
|
+
if (TypeName === "AWS::EC2::SubnetRouteTableAssociation") return json(400, { __type: "InvalidRequestException", message: "Missing Or Invalid ResourceModel property in AWS::EC2::SubnetRouteTableAssociation list handler request input" });
|
|
129
|
+
if (TypeName === "AWS::S3::Bucket") return json(400, { __type: "AccessDeniedException", message: "not authorized" });
|
|
130
|
+
return undefined;
|
|
131
|
+
});
|
|
132
|
+
const result = await listCloud(
|
|
133
|
+
{ substrate: "aws", scopeId: "000000000000", locations: ["us-east-1"], types: ["AWS::Foo::Bar", "AWS::EC2::SubnetRouteTableAssociation", "AWS::S3::Bucket"] },
|
|
134
|
+
target(),
|
|
135
|
+
{ fetcher: fake.fetcher, chains: refusingChains(), now: steppingClock(), retryDelays: [] },
|
|
136
|
+
);
|
|
137
|
+
expect(result.resources).toEqual([]);
|
|
138
|
+
expect(result.coverage.map((c) => [c.listedType, c.verdict])).toEqual([
|
|
139
|
+
["AWS::EC2::SubnetRouteTableAssociation", "unsupported-kind"],
|
|
140
|
+
["AWS::Foo::Bar", "unsupported-kind"],
|
|
141
|
+
["AWS::S3::Bucket", "no-credentials"],
|
|
142
|
+
]);
|
|
143
|
+
expect(result.notes.map((n) => [n.code, n.listedType])).toEqual([
|
|
144
|
+
["needs-parent", "AWS::EC2::SubnetRouteTableAssociation"],
|
|
145
|
+
["no-lister", "AWS::Foo::Bar"],
|
|
146
|
+
["no-credentials", "AWS::S3::Bucket"],
|
|
147
|
+
]);
|
|
148
|
+
expect(result.notes[1].message).toContain("does not support LIST");
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("filters by tag after listing, and marks coverage filtered", async () => {
|
|
152
|
+
const fake = fakeFetcher(() =>
|
|
153
|
+
json(200, {
|
|
154
|
+
ResourceDescriptions: [
|
|
155
|
+
{ Identifier: "a", Properties: JSON.stringify({ Tags: [{ Key: "env", Value: "prod" }] }) },
|
|
156
|
+
{ Identifier: "b", Properties: JSON.stringify({ Tags: [{ Key: "env", Value: "dev" }] }) },
|
|
157
|
+
],
|
|
158
|
+
}),
|
|
159
|
+
);
|
|
160
|
+
const result = await listCloud(
|
|
161
|
+
{ substrate: "aws", scopeId: "000000000000", locations: ["us-east-1"], types: ["AWS::SQS::Queue"], tagFilter: { env: "prod" } },
|
|
162
|
+
target(),
|
|
163
|
+
{ fetcher: fake.fetcher, chains: refusingChains(), now: steppingClock(), retryDelays: [] },
|
|
164
|
+
);
|
|
165
|
+
expect(result.resources.map((r) => r.nativeId)).toEqual(["a"]);
|
|
166
|
+
expect(result.coverage[0].verdict).toBe("filtered");
|
|
167
|
+
expect(result.notes.map((n) => n.code)).toEqual(["tag-filter"]);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('lists the default types for types "*" and says so', async () => {
|
|
171
|
+
const fake = fakeFetcher(() => json(200, { ResourceDescriptions: [] }));
|
|
172
|
+
const result = await listCloud(
|
|
173
|
+
{ substrate: "aws", scopeId: "000000000000", locations: ["us-east-1"], types: "*" },
|
|
174
|
+
target(),
|
|
175
|
+
{ fetcher: fake.fetcher, chains: refusingChains(), now: steppingClock(), retryDelays: [] },
|
|
176
|
+
);
|
|
177
|
+
expect(result.notes[0].code).toBe("default-types");
|
|
178
|
+
expect(fake.calls.length).toBeGreaterThan(20);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("refuses every region, which would need a call off the allowlist", async () => {
|
|
182
|
+
const fake = fakeFetcher(() => undefined);
|
|
183
|
+
await expect(
|
|
184
|
+
listCloud({ substrate: "aws", scopeId: "0", locations: "*", types: ["AWS::S3::Bucket"] }, target(), { fetcher: fake.fetcher, chains: refusingChains() }),
|
|
185
|
+
).rejects.toThrow(ListerConfigError);
|
|
186
|
+
expect(fake.calls).toEqual([]);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it("never asks the default provider chain when an endpoint is given", async () => {
|
|
190
|
+
const chains = refusingChains();
|
|
191
|
+
const fake = fakeFetcher(() => undefined);
|
|
192
|
+
await expect(
|
|
193
|
+
listCloud(
|
|
194
|
+
{ substrate: "aws", scopeId: "0", locations: ["us-east-1"], types: ["AWS::S3::Bucket"] },
|
|
195
|
+
{ substrate: "aws", aws: { endpoint: ENDPOINT } },
|
|
196
|
+
{ fetcher: fake.fetcher, chains },
|
|
197
|
+
),
|
|
198
|
+
).rejects.toThrow(/needs static credentials/);
|
|
199
|
+
expect(chains.count.aws).toBe(0);
|
|
200
|
+
expect(fake.calls).toEqual([]);
|
|
201
|
+
});
|
|
202
|
+
});
|