@intentius/chant-lexicon-aws 0.124.31 → 0.124.33
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/actions/dynamodb.js +41 -0
- package/dist/actions/ecr.js +9 -0
- package/dist/actions/ecs.js +5 -0
- package/dist/actions/iam.js +3 -0
- package/dist/actions/index.js +9 -0
- package/dist/actions/lambda.js +11 -0
- package/dist/actions/logs.js +4 -0
- package/dist/actions/s3.js +40 -0
- package/dist/actions/sns.js +5 -0
- package/dist/actions/sqs.js +15 -0
- package/dist/agentcore/trace-fetch.d.ts.map +1 -1
- package/dist/agentcore/trace-fetch.js +472 -0
- package/dist/agentcore/trace-render.js +359 -0
- package/dist/ambient.js +148 -0
- package/dist/api/credential-chain.d.ts +30 -3
- package/dist/api/credential-chain.d.ts.map +1 -1
- package/dist/api/credential-chain.js +509 -0
- package/dist/api/read-client.d.ts +16 -43
- package/dist/api/read-client.d.ts.map +1 -1
- package/dist/api/read-client.js +458 -0
- package/dist/api/sigv4.d.ts +4 -4
- package/dist/api/sigv4.js +185 -0
- package/dist/behaviour-kinds.js +114 -0
- package/dist/caller-identity.d.ts +3 -5
- package/dist/caller-identity.d.ts.map +1 -1
- package/dist/caller-identity.js +146 -0
- package/dist/codegen/docs-cli.js +2 -0
- package/dist/codegen/docs.js +120 -0
- package/dist/codegen/enum-overlay.js +162 -0
- package/dist/codegen/extensions.js +139 -0
- package/dist/codegen/fallback.js +32 -0
- package/dist/codegen/generate-cli.js +15 -0
- package/dist/codegen/generate-lexicon.js +70 -0
- package/dist/codegen/generate-typescript.js +226 -0
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/codegen/generate.js +234 -0
- package/dist/codegen/naming.js +135 -0
- package/dist/codegen/package.js +67 -0
- package/dist/codegen/patches.d.ts +26 -1
- package/dist/codegen/patches.d.ts.map +1 -1
- package/dist/codegen/patches.js +90 -0
- package/dist/codegen/property-overlay.js +85 -0
- package/dist/codegen/property-overlay.json +1 -16
- package/dist/codegen/sam.js +402 -0
- package/dist/codegen/typecheck.js +4 -0
- package/dist/codegen/versions.js +31 -0
- package/dist/components/__tests__/mock-cloud-executor.js +326 -0
- package/dist/components/apply.d.ts +44 -1
- package/dist/components/apply.d.ts.map +1 -1
- package/dist/components/apply.js +752 -0
- package/dist/components/builders.js +37 -0
- package/dist/components/capability-plugin.js +66 -0
- package/dist/components/cloud-executor.d.ts +35 -0
- package/dist/components/cloud-executor.d.ts.map +1 -1
- package/dist/components/cloud-executor.js +576 -0
- package/dist/components/config-bom.js +207 -0
- package/dist/components/host-delivery.js +117 -0
- package/dist/components/index.js +18 -0
- package/dist/components/job-submission.js +77 -0
- package/dist/components/publish.js +234 -0
- package/dist/components/safety.js +62 -0
- package/dist/components/wait-aws.js +68 -0
- package/dist/composites/agentcore-agent.js +187 -0
- package/dist/composites/agentcore-trust-policy.js +13 -0
- package/dist/composites/alb-shared.js +84 -0
- package/dist/composites/bucket-deployment.js +93 -0
- package/dist/composites/catalog.js +2714 -0
- package/dist/composites/dynamodb-table.js +66 -0
- package/dist/composites/ec2-instance-bundle.js +75 -0
- package/dist/composites/ec2-instance-role.js +26 -0
- package/dist/composites/ecr-repository.js +64 -0
- package/dist/composites/ecs-trust-policy.js +10 -0
- package/dist/composites/efs-with-access-point.js +44 -0
- package/dist/composites/eks-cluster.js +118 -0
- package/dist/composites/fargate-alb.js +216 -0
- package/dist/composites/fargate-service.js +222 -0
- package/dist/composites/index.js +28 -0
- package/dist/composites/lambda-api.js +15 -0
- package/dist/composites/lambda-dynamodb.js +77 -0
- package/dist/composites/lambda-eventbridge.js +27 -0
- package/dist/composites/lambda-function.js +54 -0
- package/dist/composites/lambda-s3.js +93 -0
- package/dist/composites/lambda-sns.js +23 -0
- package/dist/composites/lambda-sqs.js +34 -0
- package/dist/composites/landing-zone.js +82 -0
- package/dist/composites/microvm-app.js +293 -0
- package/dist/composites/minimal-vpc.js +40 -0
- package/dist/composites/monitoring-stack.js +105 -0
- package/dist/composites/nlb-service.js +61 -0
- package/dist/composites/rds-instance.js +98 -0
- package/dist/composites/scheduled-lambda.js +28 -0
- package/dist/composites/solr-fargate-service.js +33 -0
- package/dist/composites/step-functions-workflow.js +78 -0
- package/dist/composites/vpc-default.js +132 -0
- package/dist/condition.js +43 -0
- package/dist/coverage.js +4 -0
- package/dist/deep-observe.d.ts.map +1 -1
- package/dist/deep-observe.js +709 -0
- package/dist/deep-topology.js +226 -0
- package/dist/default-tags.js +50 -0
- package/dist/defaults.js +85 -0
- package/dist/dependencies.js +269 -0
- package/dist/detect.js +21 -0
- package/dist/disruption.d.ts.map +1 -1
- package/dist/disruption.js +129 -0
- package/dist/effect-receipt-row.js +107 -0
- package/dist/generated/index.d.ts +1297 -82
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +12382 -0
- package/dist/generated/runtime.js +4 -0
- package/dist/governance.js +131 -0
- package/dist/health.d.ts +61 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +216 -0
- package/dist/identity-observe.d.ts.map +1 -1
- package/dist/identity-observe.js +127 -0
- package/dist/import/generator.js +757 -0
- package/dist/import/live-export.js +34 -0
- package/dist/import/parser.js +394 -0
- package/dist/index.js +69 -0
- package/dist/integrity.json +6 -6
- package/dist/intrinsics.js +393 -0
- package/dist/lint/audit-catalog.js +87 -0
- package/dist/lint/audit-lineage.js +150 -0
- package/dist/lint/post-synth/cf-refs.js +247 -0
- package/dist/lint/post-synth/cor020.js +60 -0
- package/dist/lint/post-synth/ext001.d.ts.map +1 -1
- package/dist/lint/post-synth/ext001.js +197 -0
- package/dist/lint/post-synth/index.js +124 -0
- package/dist/lint/post-synth/waw010.js +41 -0
- package/dist/lint/post-synth/waw011.js +41 -0
- package/dist/lint/post-synth/waw013.js +38 -0
- package/dist/lint/post-synth/waw014.js +42 -0
- package/dist/lint/post-synth/waw015.js +88 -0
- package/dist/lint/post-synth/waw016.d.ts.map +1 -1
- package/dist/lint/post-synth/waw016.js +116 -0
- package/dist/lint/post-synth/waw017.js +43 -0
- package/dist/lint/post-synth/waw018.js +61 -0
- package/dist/lint/post-synth/waw019.js +64 -0
- package/dist/lint/post-synth/waw020.js +56 -0
- package/dist/lint/post-synth/waw021.js +44 -0
- package/dist/lint/post-synth/waw022.js +36 -0
- package/dist/lint/post-synth/waw023.js +40 -0
- package/dist/lint/post-synth/waw024.js +46 -0
- package/dist/lint/post-synth/waw025.js +36 -0
- package/dist/lint/post-synth/waw026.js +38 -0
- package/dist/lint/post-synth/waw027.js +41 -0
- package/dist/lint/post-synth/waw028.js +39 -0
- package/dist/lint/post-synth/waw029.js +54 -0
- package/dist/lint/post-synth/waw030.js +282 -0
- package/dist/lint/post-synth/waw031.js +58 -0
- package/dist/lint/post-synth/waw032.js +45 -0
- package/dist/lint/post-synth/waw033.js +75 -0
- package/dist/lint/post-synth/waw034.js +52 -0
- package/dist/lint/post-synth/waw035.js +56 -0
- package/dist/lint/post-synth/waw036.js +79 -0
- package/dist/lint/post-synth/waw037.js +67 -0
- package/dist/lint/post-synth/waw038.js +42 -0
- package/dist/lint/post-synth/waw039.js +42 -0
- package/dist/lint/post-synth/waw040.js +45 -0
- package/dist/lint/post-synth/waw041.js +40 -0
- package/dist/lint/post-synth/waw042.js +99 -0
- package/dist/lint/post-synth/waw043.js +51 -0
- package/dist/lint/post-synth/waw044.js +64 -0
- package/dist/lint/post-synth/waw045.js +49 -0
- package/dist/lint/post-synth/waw046.js +52 -0
- package/dist/lint/post-synth/waw047.js +43 -0
- package/dist/lint/post-synth/waw048.js +40 -0
- package/dist/lint/post-synth/waw049.js +78 -0
- package/dist/lint/post-synth/waw050.js +44 -0
- package/dist/lint/post-synth/waw051.js +41 -0
- package/dist/lint/post-synth/waw052.js +43 -0
- package/dist/lint/post-synth/waw053.js +43 -0
- package/dist/lint/post-synth/waw054.js +41 -0
- package/dist/lint/post-synth/waw055.js +41 -0
- package/dist/lint/post-synth/waw056.js +65 -0
- package/dist/lint/post-synth/waw057.js +43 -0
- package/dist/lint/post-synth/waw058.js +61 -0
- package/dist/lint/post-synth/waw059.js +338 -0
- package/dist/lint/post-synth/waw060.js +83 -0
- package/dist/lint/post-synth/waw061.js +60 -0
- package/dist/lint/post-synth/waw062.js +0 -0
- package/dist/lint/post-synth/waw063.js +0 -0
- package/dist/lint/post-synth/waw064.js +45 -0
- package/dist/lint/post-synth/waw065.js +104 -0
- package/dist/lint/post-synth/waw066.js +145 -0
- package/dist/lint/post-synth/waw067.js +115 -0
- package/dist/lint/post-synth/waw068.js +69 -0
- package/dist/lint/post-synth/waw069.js +0 -0
- package/dist/lint/rules/hardcoded-region.js +38 -0
- package/dist/lint/rules/iam-wildcard.js +60 -0
- package/dist/lint/rules/index.js +6 -0
- package/dist/lint/rules/s3-encryption.js +60 -0
- package/dist/live-attrs.js +42 -0
- package/dist/lsp/completions.d.ts.map +1 -1
- package/dist/lsp/completions.js +18 -0
- package/dist/lsp/hover.d.ts.map +1 -1
- package/dist/lsp/hover.js +66 -0
- package/dist/manifest.json +1 -1
- package/dist/mapping.js +33 -0
- package/dist/meta.json +17359 -784
- package/dist/nested-stack.js +95 -0
- package/dist/okf/index.md +203 -0
- package/dist/okf/rules/EXT001.md +1 -0
- package/dist/okf/rules/WAW016.md +2 -0
- package/dist/okf/rules/WAW019.md +1 -0
- package/dist/okf/rules/WAW028.md +1 -0
- package/dist/okf/rules/WAW030.md +2 -0
- package/dist/okf/rules/WAW039.md +1 -0
- package/dist/okf/rules/WAW049.md +1 -0
- package/dist/okf/rules/WAW056.md +1 -0
- package/dist/okf/rules/WAW058.md +1 -0
- package/dist/okf/rules/WAW062.md +1 -0
- package/dist/okf/rules/WAW064.md +1 -0
- package/dist/okf/rules/WAW065.md +1 -0
- package/dist/okf/rules/WAW066.md +1 -0
- package/dist/okf/rules/WAW067.md +1 -0
- package/dist/okf/rules/WAW068.md +1 -0
- package/dist/okf/rules/WAW069.md +4 -0
- package/dist/okf/types/AIWorkloadConfig.md +23 -0
- package/dist/okf/types/ARCRegionSwitchPlan.md +1 -0
- package/dist/okf/types/AccountAccessApplication.md +28 -0
- package/dist/okf/types/AccountAccessEntitlement.md +22 -0
- package/dist/okf/types/ActionTarget.md +20 -0
- package/dist/okf/types/AdConfiguration.md +21 -0
- package/dist/okf/types/Adapter.md +26 -0
- package/dist/okf/types/AgentContext.md +35 -0
- package/dist/okf/types/AgentGoal.md +31 -0
- package/dist/okf/types/AgentProfile.md +34 -0
- package/dist/okf/types/Alarm.md +3 -1
- package/dist/okf/types/AlarmModel.md +14 -9
- package/dist/okf/types/AmplifyWebhook.md +25 -0
- package/dist/okf/types/ApiCache.md +8 -8
- package/dist/okf/types/ApiGatewayManagedOverrides.md +5 -5
- package/dist/okf/types/AppAuthorization.md +35 -0
- package/dist/okf/types/AppBlockBuilder.md +1 -0
- package/dist/okf/types/AppInstance.md +2 -2
- package/dist/okf/types/AppInstanceBot.md +2 -2
- package/dist/okf/types/AppStreamFleet.md +3 -2
- package/dist/okf/types/AppSyncApiKey.md +6 -6
- package/dist/okf/types/AppSyncType.md +22 -0
- package/dist/okf/types/ApplicationStatusCheck.md +36 -0
- package/dist/okf/types/ApplicationVersion.md +4 -1
- package/dist/okf/types/ApplicationsList.md +26 -0
- package/dist/okf/types/ApprovalPolicy.md +28 -0
- package/dist/okf/types/ArchiveRule.md +24 -0
- package/dist/okf/types/Asset.md +30 -0
- package/dist/okf/types/Backup.md +31 -0
- package/dist/okf/types/BedrockAgentCoreDataset.md +1 -1
- package/dist/okf/types/BedrockAgentCoreGateway.md +3 -0
- package/dist/okf/types/BedrockSession.md +28 -0
- package/dist/okf/types/BillEstimate.md +35 -0
- package/dist/okf/types/Brand.md +32 -0
- package/dist/okf/types/CallAnalyticsCategory.md +25 -0
- package/dist/okf/types/Campaign.md +28 -0
- package/dist/okf/types/CapacityProvider.md +30 -0
- package/dist/okf/types/Case.md +24 -0
- package/dist/okf/types/CertificateAssociation.md +13 -0
- package/dist/okf/types/ChangeSet.md +36 -0
- package/dist/okf/types/ChannelFlow.md +29 -0
- package/dist/okf/types/ChimeChannel.md +39 -0
- package/dist/okf/types/Classifier.md +6 -6
- package/dist/okf/types/ClientVpnAuthorizationRule.md +6 -6
- package/dist/okf/types/ClientVpnEndpoint.md +2 -0
- package/dist/okf/types/ClientVpnRoute.md +5 -5
- package/dist/okf/types/CloudConnector.md +29 -0
- package/dist/okf/types/Cluster.md +39 -0
- package/dist/okf/types/ClusterSchedulerConfig.md +30 -0
- package/dist/okf/types/CodeCommitRepository.md +12 -12
- package/dist/okf/types/CodeConnectionsHost.md +26 -0
- package/dist/okf/types/CodeRepository.md +5 -5
- package/dist/okf/types/CompositeAlarm.md +1 -0
- package/dist/okf/types/ComputeEnvironment.md +2 -0
- package/dist/okf/types/ComputeNodeGroup.md +1 -1
- package/dist/okf/types/ComputeQuota.md +34 -0
- package/dist/okf/types/ConfigRule.md +1 -1
- package/dist/okf/types/ConfigurationRecorder.md +7 -6
- package/dist/okf/types/ConnectAttachment.md +2 -0
- package/dist/okf/types/ConnectQueue.md +5 -1
- package/dist/okf/types/ConnectVocabulary.md +28 -0
- package/dist/okf/types/ConnectionType.md +24 -0
- package/dist/okf/types/ConsentPortal.md +33 -0
- package/dist/okf/types/ContactMethod.md +29 -0
- package/dist/okf/types/ContainerAssociation.md +26 -0
- package/dist/okf/types/ContainerFleet.md +1 -1
- package/dist/okf/types/ContainerGroupDefinition.md +1 -1
- package/dist/okf/types/Content.md +40 -0
- package/dist/okf/types/ContentAssociation.md +28 -0
- package/dist/okf/types/CustomDetectionRuleAssociation.md +28 -0
- package/dist/okf/types/CustomEntityType.md +4 -9
- package/dist/okf/types/Customization.md +22 -0
- package/dist/okf/types/CwIntegration.md +31 -0
- package/dist/okf/types/DAXParameterGroup.md +3 -8
- package/dist/okf/types/DAXSubnetGroup.md +0 -5
- package/dist/okf/types/DBClusterEndpoint.md +31 -0
- package/dist/okf/types/DBProxyTargetGroup.md +1 -0
- package/dist/okf/types/DBSnapshot.md +62 -0
- package/dist/okf/types/DLMLifecyclePolicy.md +12 -12
- package/dist/okf/types/DLPSetting.md +31 -0
- package/dist/okf/types/DMSInstanceProfile.md +1 -1
- package/dist/okf/types/DRSLaunchConfigurationTemplate.md +28 -0
- package/dist/okf/types/Daemon.md +1 -0
- package/dist/okf/types/DataExchangeDataSet.md +29 -0
- package/dist/okf/types/DataIntegrationFlow.md +27 -0
- package/dist/okf/types/DataMigration.md +1 -1
- package/dist/okf/types/DataProvider.md +2 -1
- package/dist/okf/types/DataQualityRuleset.md +6 -11
- package/dist/okf/types/DataSource.md +23 -0
- package/dist/okf/types/Dataset.md +20 -0
- package/dist/okf/types/DatasetIntegration.md +23 -0
- package/dist/okf/types/DbCluster.md +1 -1
- package/dist/okf/types/DbInstance.md +8 -2
- package/dist/okf/types/DeadlineBudget.md +29 -0
- package/dist/okf/types/DelegationSet.md +23 -0
- package/dist/okf/types/DeliveryChannel.md +6 -11
- package/dist/okf/types/DevOpsAgentAgentSpace.md +4 -0
- package/dist/okf/types/DevOpsAgentService.md +1 -0
- package/dist/okf/types/DevOpsAgentTrigger.md +28 -0
- package/dist/okf/types/DirectConnectGatewayAttachment.md +2 -0
- package/dist/okf/types/Directory.md +60 -0
- package/dist/okf/types/DocDBDBClusterParameterGroup.md +5 -10
- package/dist/okf/types/DocDBDBSubnetGroup.md +4 -9
- package/dist/okf/types/DocDBElasticClusterSnapshot.md +36 -0
- package/dist/okf/types/DocumentClassifierEndpoint.md +27 -0
- package/dist/okf/types/Domain.md +27 -0
- package/dist/okf/types/EKSCertificateAuthority.md +42 -0
- package/dist/okf/types/EKSCluster.md +8 -0
- package/dist/okf/types/EcSnapshot.md +66 -0
- package/dist/okf/types/EmailIdentityCertificate.md +15 -0
- package/dist/okf/types/EndpointConfig.md +14 -13
- package/dist/okf/types/EntityRecognizer.md +27 -0
- package/dist/okf/types/EntityRecognizerEndpoint.md +31 -0
- package/dist/okf/types/EnvironmentEC2.md +13 -13
- package/dist/okf/types/EvaluationForm.md +1 -0
- package/dist/okf/types/Evaluator.md +6 -2
- package/dist/okf/types/EventAction.md +26 -0
- package/dist/okf/types/EventRule.md +2 -0
- package/dist/okf/types/EventSource.md +30 -0
- package/dist/okf/types/EventTracker.md +22 -0
- package/dist/okf/types/EventsV2EventBus.md +28 -0
- package/dist/okf/types/EventsV2ResourcePolicy.md +19 -0
- package/dist/okf/types/EventsV2Subscriber.md +39 -0
- package/dist/okf/types/ExperimentDefinition.md +39 -0
- package/dist/okf/types/ExperimentRun.md +33 -0
- package/dist/okf/types/ExperimentTrialComponent.md +13 -11
- package/dist/okf/types/FHIRDatastore.md +3 -0
- package/dist/okf/types/FSxSnapshot.md +5 -5
- package/dist/okf/types/FSxVolume.md +9 -9
- package/dist/okf/types/FeaturedResultsSet.md +26 -0
- package/dist/okf/types/Feed.md +1 -0
- package/dist/okf/types/FieldLevelEncryptionConfig.md +25 -0
- package/dist/okf/types/FieldLevelEncryptionProfile.md +22 -0
- package/dist/okf/types/FileCache.md +45 -0
- package/dist/okf/types/Filter.md +27 -0
- package/dist/okf/types/Firewall.md +6 -0
- package/dist/okf/types/FlowMediaStream.md +28 -0
- package/dist/okf/types/FlowOutput.md +1 -0
- package/dist/okf/types/FpgaImage.md +38 -0
- package/dist/okf/types/Function.md +2 -2
- package/dist/okf/types/Gateway.md +41 -0
- package/dist/okf/types/GatewayClusterAssociations.md +23 -0
- package/dist/okf/types/GatewayRateLimit.md +26 -0
- package/dist/okf/types/GatewayRule.md +32 -0
- package/dist/okf/types/GlobalReplicationGroup.md +3 -0
- package/dist/okf/types/GlobalResolver.md +1 -1
- package/dist/okf/types/GlobalTable.md +1 -0
- package/dist/okf/types/GlueConnection.md +5 -4
- package/dist/okf/types/GlueSecurityConfiguration.md +1 -6
- package/dist/okf/types/GlueSession.md +38 -0
- package/dist/okf/types/GlueTable.md +5 -10
- package/dist/okf/types/GlueWorkflow.md +5 -10
- package/dist/okf/types/Group.md +27 -0
- package/dist/okf/types/Harness.md +1 -0
- package/dist/okf/types/HostKey.md +33 -0
- package/dist/okf/types/HostedZone.md +1 -0
- package/dist/okf/types/HttpApi.md +2 -0
- package/dist/okf/types/HttpNamespace.md +5 -5
- package/dist/okf/types/HubV2.md +1 -0
- package/dist/okf/types/HumanTaskUi.md +22 -0
- package/dist/okf/types/IPv4Pool.md +28 -0
- package/dist/okf/types/ImageBuilder.md +1 -0
- package/dist/okf/types/ImageBuilderImage.md +1 -1
- package/dist/okf/types/ImagePipeline.md +1 -1
- package/dist/okf/types/InferenceComponent.md +5 -1
- package/dist/okf/types/InfluxDBBackup.md +65 -0
- package/dist/okf/types/InfluxDBCluster.md +3 -0
- package/dist/okf/types/InfrastructureConfiguration.md +2 -0
- package/dist/okf/types/IngestionDestination.md +28 -0
- package/dist/okf/types/InputSecurityGroup.md +6 -4
- package/dist/okf/types/InspectorV2Connector.md +38 -0
- package/dist/okf/types/InstanceEventWindow.md +25 -0
- package/dist/okf/types/InstanceFleetConfig.md +10 -10
- package/dist/okf/types/InstanceGroupConfig.md +3 -3
- package/dist/okf/types/InstrumentationConfig.md +31 -0
- package/dist/okf/types/IntegrationAssociation.md +3 -0
- package/dist/okf/types/IoTSiteWiseApplication.md +34 -0
- package/dist/okf/types/IoTSiteWiseDataset.md +5 -2
- package/dist/okf/types/IoTSiteWiseTask.md +24 -0
- package/dist/okf/types/IpamExternalResourceVerificationToken.md +35 -0
- package/dist/okf/types/IpamInternetRegistryAssociation.md +32 -0
- package/dist/okf/types/Job.md +35 -0
- package/dist/okf/types/JobTemplate.md +26 -0
- package/dist/okf/types/KinesisChannel.md +31 -0
- package/dist/okf/types/KinesisStream.md +1 -0
- package/dist/okf/types/LambdaResourcePolicy.md +14 -0
- package/dist/okf/types/Lexicon.md +34 -0
- package/dist/okf/types/LicenseAssetGroup.md +23 -0
- package/dist/okf/types/LicenseConfiguration.md +33 -0
- package/dist/okf/types/LicenseServerEndpoint.md +32 -0
- package/dist/okf/types/LightsailKeyPair.md +29 -0
- package/dist/okf/types/LimitsProfile.md +27 -0
- package/dist/okf/types/LocationAzureBlob.md +2 -1
- package/dist/okf/types/LocationObjectStorage.md +1 -0
- package/dist/okf/types/LogAlarm.md +2 -0
- package/dist/okf/types/MGNConnector.md +23 -0
- package/dist/okf/types/MGNLaunchConfigurationTemplate.md +37 -0
- package/dist/okf/types/MLTransform.md +15 -15
- package/dist/okf/types/MWAAServerlessWorkflow.md +3 -0
- package/dist/okf/types/ManagedNotificationAccountContactAssociation.md +1 -0
- package/dist/okf/types/ManagedNotificationAdditionalChannelAssociation.md +1 -0
- package/dist/okf/types/MediaConvertJobTemplate.md +11 -13
- package/dist/okf/types/MediaConvertQueue.md +8 -10
- package/dist/okf/types/MediaInsightsPipelineConfiguration.md +28 -0
- package/dist/okf/types/MediaLiveInput.md +41 -18
- package/dist/okf/types/MediaPackageV2Channel.md +3 -0
- package/dist/okf/types/MediaPackageV2OriginEndpoint.md +1 -0
- package/dist/okf/types/MediaPipelineKinesisVideoStreamPool.md +28 -0
- package/dist/okf/types/MediaTailorFunction.md +27 -0
- package/dist/okf/types/MedicalVocabulary.md +21 -0
- package/dist/okf/types/Member.md +26 -0
- package/dist/okf/types/Memory.md +6 -0
- package/dist/okf/types/MemoryDBSnapshot.md +29 -0
- package/dist/okf/types/Metric.md +59 -0
- package/dist/okf/types/MetricAttribution.md +23 -0
- package/dist/okf/types/MicrosoftAD.md +11 -11
- package/dist/okf/types/MigrationProject.md +8 -1
- package/dist/okf/types/Monitor.md +26 -0
- package/dist/okf/types/NFSFileShare.md +44 -0
- package/dist/okf/types/NeptuneGraphGraph.md +1 -0
- package/dist/okf/types/NetworkConnector.md +4 -0
- package/dist/okf/types/NetworkFlowMonitorScope.md +23 -0
- package/dist/okf/types/NetworkMigrationDefinition.md +31 -0
- package/dist/okf/types/NetworkSecurityManagerDeployment.md +31 -0
- package/dist/okf/types/NetworkSecurityManagerPolicy.md +32 -0
- package/dist/okf/types/NetworkSecurityManagerScope.md +29 -0
- package/dist/okf/types/NotebookInstance.md +18 -18
- package/dist/okf/types/NotebookInstanceLifecycleConfig.md +6 -5
- package/dist/okf/types/NotifyConfiguration.md +35 -0
- package/dist/okf/types/OTelEnrichment.md +2 -0
- package/dist/okf/types/OnlineEvaluationConfig.md +0 -1
- package/dist/okf/types/OrganizationConfigRule.md +7 -7
- package/dist/okf/types/Outpost.md +32 -0
- package/dist/okf/types/ParallelData.md +40 -0
- package/dist/okf/types/Partition.md +5 -5
- package/dist/okf/types/PaymentConnector.md +4 -1
- package/dist/okf/types/Pentest.md +1 -0
- package/dist/okf/types/PerfReports.md +28 -0
- package/dist/okf/types/PermissionAssociation.md +30 -0
- package/dist/okf/types/PersonalizeDataset.md +1 -0
- package/dist/okf/types/PersonalizeDatasetGroup.md +1 -0
- package/dist/okf/types/PersonalizeSchema.md +1 -0
- package/dist/okf/types/Pipeline.md +25 -0
- package/dist/okf/types/PlaybackConfiguration.md +1 -0
- package/dist/okf/types/PolicyAssociation.md +1 -1
- package/dist/okf/types/PolicyGrant.md +2 -2
- package/dist/okf/types/PolicyPrincipalAttachment.md +2 -7
- package/dist/okf/types/PortalProduct.md +24 -0
- package/dist/okf/types/PrefetchSchedule.md +25 -0
- package/dist/okf/types/PricingPlanManagerSubscription.md +31 -0
- package/dist/okf/types/PrincipalAssociation.md +27 -0
- package/dist/okf/types/PrivateDnsNamespace.md +8 -8
- package/dist/okf/types/PrivateVirtualInterface.md +1 -0
- package/dist/okf/types/ProcurementPortalPreference.md +45 -0
- package/dist/okf/types/Program.md +33 -0
- package/dist/okf/types/ProjectMembership.md +1 -1
- package/dist/okf/types/ProtocolsList.md +26 -0
- package/dist/okf/types/PublicDnsNamespace.md +7 -7
- package/dist/okf/types/PublicVirtualInterface.md +1 -0
- package/dist/okf/types/QEV2IdcApplication.md +25 -0
- package/dist/okf/types/QueryLoggingConfig.md +21 -0
- package/dist/okf/types/QuerySuggestionsBlockList.md +25 -0
- package/dist/okf/types/QuickSightAssignment.md +24 -0
- package/dist/okf/types/RAMResourceAssociation.md +27 -0
- package/dist/okf/types/RDSClusterSnapshot.md +54 -0
- package/dist/okf/types/RDSDBParameterGroup.md +5 -0
- package/dist/okf/types/RDSDeployment.md +41 -0
- package/dist/okf/types/RcsAgent.md +38 -0
- package/dist/okf/types/ReceiptRule.md +5 -5
- package/dist/okf/types/ReceiptRuleSet.md +1 -6
- package/dist/okf/types/RecommenderFilter.md +27 -0
- package/dist/okf/types/RecommenderSchema.md +25 -0
- package/dist/okf/types/RecordSet.md +16 -22
- package/dist/okf/types/RecoveryPlan.md +28 -0
- package/dist/okf/types/RedshiftIdcApplication.md +31 -0
- package/dist/okf/types/RedshiftSnapshot.md +59 -0
- package/dist/okf/types/RegistrationAttachment.md +28 -0
- package/dist/okf/types/Registry.md +41 -0
- package/dist/okf/types/RegistryRecord.md +38 -0
- package/dist/okf/types/RelatedItem.md +24 -0
- package/dist/okf/types/ReplicationConfigurationTemplate.md +35 -0
- package/dist/okf/types/ReplicationSubnetGroup.md +4 -9
- package/dist/okf/types/ReplicationTask.md +14 -14
- package/dist/okf/types/ReportGenerator.md +29 -0
- package/dist/okf/types/ReportGroup.md +1 -3
- package/dist/okf/types/ResilienceHubV2Policy.md +1 -0
- package/dist/okf/types/ResilienceHubV2Service.md +1 -0
- package/dist/okf/types/ResourceConfiguration.md +1 -1
- package/dist/okf/types/ResourceMetricsConfiguration.md +21 -0
- package/dist/okf/types/RestApi.md +1 -0
- package/dist/okf/types/RetrievalInstruction.md +32 -0
- package/dist/okf/types/RouterOutput.md +1 -0
- package/dist/okf/types/Rule.md +31 -0
- package/dist/okf/types/RunCache.md +29 -0
- package/dist/okf/types/Runtime.md +2 -1
- package/dist/okf/types/SCNInstance.md +33 -0
- package/dist/okf/types/SDBDomain.md +2 -2
- package/dist/okf/types/SMBFileShare.md +49 -0
- package/dist/okf/types/SageMakerArtifact.md +27 -0
- package/dist/okf/types/SageMakerEndpoint.md +0 -1
- package/dist/okf/types/ScalableTarget.md +1 -0
- package/dist/okf/types/ScalingPlan.md +6 -6
- package/dist/okf/types/ScheduledReport.md +31 -0
- package/dist/okf/types/SecondaryNetwork.md +26 -0
- package/dist/okf/types/SecurityAgentArtifact.md +25 -0
- package/dist/okf/types/SecurityAgentIntegration.md +31 -0
- package/dist/okf/types/Server.md +1 -0
- package/dist/okf/types/ServerlessCache.md +2 -0
- package/dist/okf/types/ServerlessCacheSnapshot.md +31 -0
- package/dist/okf/types/ServerlessRepoApplication.md +32 -0
- package/dist/okf/types/ServiceDiscoveryInstance.md +3 -7
- package/dist/okf/types/SipMediaApplication.md +27 -0
- package/dist/okf/types/SiteToSiteVpnAttachment.md +2 -0
- package/dist/okf/types/SnapshotCopyGrant.md +20 -0
- package/dist/okf/types/Solution.md +1 -0
- package/dist/okf/types/SourceAssociation.md +25 -0
- package/dist/okf/types/SourceCredential.md +6 -6
- package/dist/okf/types/SourceNetwork.md +23 -0
- package/dist/okf/types/StackFleetAssociation.md +2 -7
- package/dist/okf/types/StorageTierPolicy.md +20 -0
- package/dist/okf/types/StorageVirtualMachine.md +9 -9
- package/dist/okf/types/Stream.md +28 -0
- package/dist/okf/types/SubnetCidrReservation.md +26 -0
- package/dist/okf/types/SubscriptionProvider.md +26 -0
- package/dist/okf/types/SupportPermit.md +29 -0
- package/dist/okf/types/Table.md +2 -1
- package/dist/okf/types/TableOptimizer.md +5 -10
- package/dist/okf/types/Tape.md +31 -0
- package/dist/okf/types/Template.md +36 -0
- package/dist/okf/types/Tenant.md +2 -0
- package/dist/okf/types/Terminology.md +39 -0
- package/dist/okf/types/Thesaurus.md +25 -0
- package/dist/okf/types/ThingPrincipalAttachment.md +3 -8
- package/dist/okf/types/Topic.md +1 -0
- package/dist/okf/types/TopicRuleDestination.md +1 -0
- package/dist/okf/types/TrafficPolicy.md +26 -0
- package/dist/okf/types/TrafficPolicyInstance.md +28 -0
- package/dist/okf/types/TranscribeVocabulary.md +27 -0
- package/dist/okf/types/TransitGatewayRouteTableAttachment.md +2 -0
- package/dist/okf/types/TransitVirtualInterface.md +1 -0
- package/dist/okf/types/Tunnel.md +25 -0
- package/dist/okf/types/UsageLimit.md +26 -0
- package/dist/okf/types/UseCase.md +23 -0
- package/dist/okf/types/User.md +47 -0
- package/dist/okf/types/VPCEndpoint.md +1 -1
- package/dist/okf/types/VPCEndpointService.md +6 -0
- package/dist/okf/types/VPCPeeringConnection.md +2 -2
- package/dist/okf/types/VPNConcentrator.md +1 -1
- package/dist/okf/types/VPNConnection.md +1 -1
- package/dist/okf/types/VerifiedDestinationNumber.md +25 -0
- package/dist/okf/types/View.md +27 -0
- package/dist/okf/types/VoiceConnector.md +30 -0
- package/dist/okf/types/Volume.md +44 -0
- package/dist/okf/types/Vpc.md +1 -1
- package/dist/okf/types/VpcAttachment.md +2 -0
- package/dist/okf/types/WebFunction.md +27 -0
- package/dist/okf/types/WebFunctionEndpoint.md +44 -0
- package/dist/okf/types/WebFunctionRevision.md +32 -0
- package/dist/okf/types/WickrNetwork.md +27 -0
- package/dist/okf/types/Worker.md +29 -0
- package/dist/okf/types/Workforce.md +26 -0
- package/dist/okf/types/Workload.md +35 -0
- package/dist/okf/types/WorkloadEstimate.md +35 -0
- package/dist/okf/types/Workspace.md +28 -0
- package/dist/okf/types/Workteam.md +8 -8
- package/dist/op/activities/aws-apply.js +214 -0
- package/dist/op/activities/floci.js +97 -0
- package/dist/op/activities/index.js +32 -0
- package/dist/op/builders.js +50 -0
- package/dist/ownership.js +52 -0
- package/dist/package-cli.js +25 -0
- package/dist/parameter.js +19 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +1012 -0
- package/dist/properties.js +166 -0
- package/dist/pseudo.js +25 -0
- package/dist/receipt-store.d.ts.map +1 -1
- package/dist/receipt-store.js +233 -0
- package/dist/reference-catalog.js +106 -0
- package/dist/rules/ext001.ts +3 -3
- package/dist/rules/waw016.ts +2 -2
- package/dist/serializer.js +529 -0
- package/dist/spec/fetch.js +193 -0
- package/dist/spec/parse.js +259 -0
- package/dist/spec/pin.js +185 -0
- package/dist/spec/pinned-types.json +203 -0
- package/dist/stack-errors.js +14 -0
- package/dist/taggable.d.ts.map +1 -1
- package/dist/taggable.js +33 -0
- package/dist/teardown.js +199 -0
- package/dist/template-sections.js +53 -0
- package/dist/template-transform.js +50 -0
- package/dist/types/index.d.ts +18847 -1124
- package/dist/validate-cli.js +16 -0
- package/dist/validate.js +33 -0
- package/package.json +9 -9
- package/src/agentcore/trace-fetch.ts +2 -1
- package/src/api/credential-chain.ts +119 -9
- package/src/api/credential-isolation.test.ts +72 -0
- package/src/api/read-client-chain.test.ts +159 -0
- package/src/api/read-client.ts +42 -6
- package/src/api/sigv4.ts +4 -4
- package/src/caller-identity.ts +3 -5
- package/src/codegen/any-budget.test.ts +12 -2
- package/src/codegen/generate.ts +9 -0
- package/src/codegen/package.ts +2 -2
- package/src/codegen/patches.test.ts +95 -0
- package/src/codegen/patches.ts +53 -9
- package/src/codegen/property-overlay.json +1 -16
- package/src/components/apply.ts +218 -6
- package/src/components/cfn-plan-floci.e2e.test.ts +76 -0
- package/src/components/cfn-plan.test.ts +225 -16
- package/src/components/cloud-executor.ts +73 -25
- package/src/deep-observe.ts +2 -1
- package/src/disruption.ts +2 -1
- package/src/generated/index.d.ts +18847 -1124
- package/src/generated/index.ts +1376 -161
- package/src/generated/lexicon-aws.json +17359 -784
- package/src/health.test.ts +136 -0
- package/src/health.ts +281 -0
- package/src/identity-observe.ts +2 -1
- package/src/lint/post-synth/ext001.ts +3 -3
- package/src/lint/post-synth/waw016.ts +2 -2
- package/src/lsp/completions.ts +2 -1
- package/src/lsp/hover.ts +2 -1
- package/src/plugin.ts +10 -1
- package/src/receipt-store.ts +2 -1
- package/src/spec/pin.ts +3 -3
- package/src/spec/pinned-types.json +203 -0
- package/src/taggable.ts +2 -2
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS governance authoring: the desired-state config
|
|
3
|
+
* shape an external governance reconciler applies, and `landingZoneConfig()` —
|
|
4
|
+
* the typed authoring layer that emits it.
|
|
5
|
+
*
|
|
6
|
+
* This is deliberately NOT a composite. The evaluability rules (EVL002/004,
|
|
7
|
+
* #916/#952) require composites to declare a fixed set of resources, so a
|
|
8
|
+
* data-driven OU tree walker cannot be one. The split mirrors the SCM
|
|
9
|
+
* reconcilers: authoring emits config (this module, arbitrary cardinality);
|
|
10
|
+
* resources for greenfield bootstrap are the fixed-shape composites in
|
|
11
|
+
* `composites/landing-zone.ts`; the reconciler consumes only the config.
|
|
12
|
+
*
|
|
13
|
+
* GCP (Folder/OrgPolicy/AuditConfig) and Azure (blocked on #1545)
|
|
14
|
+
* counterparts followed the same shape.
|
|
15
|
+
*/
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Baseline guardrails (shared with the bootstrap composites)
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
export const DENY_LEAVE_ORGANIZATION = {
|
|
20
|
+
description: "Member accounts may not remove themselves from the organization.",
|
|
21
|
+
document: {
|
|
22
|
+
Version: "2012-10-17",
|
|
23
|
+
Statement: [{ Effect: "Deny", Action: "organizations:LeaveOrganization", Resource: "*" }],
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export const DENY_AUDIT_TAMPER = {
|
|
27
|
+
description: "Audit trails and recorders cannot be stopped or deleted from member accounts.",
|
|
28
|
+
document: {
|
|
29
|
+
Version: "2012-10-17",
|
|
30
|
+
Statement: [
|
|
31
|
+
{
|
|
32
|
+
Effect: "Deny",
|
|
33
|
+
Action: [
|
|
34
|
+
"cloudtrail:StopLogging",
|
|
35
|
+
"cloudtrail:DeleteTrail",
|
|
36
|
+
"config:StopConfigurationRecorder",
|
|
37
|
+
"config:DeleteConfigurationRecorder",
|
|
38
|
+
"config:DeleteDeliveryChannel",
|
|
39
|
+
],
|
|
40
|
+
Resource: "*",
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
/** Deny requests outside `regions`, excepting global services. */
|
|
46
|
+
export function regionRestriction(regions) {
|
|
47
|
+
return {
|
|
48
|
+
description: `Deny requests outside [${regions.join(", ")}] except global services.`,
|
|
49
|
+
document: {
|
|
50
|
+
Version: "2012-10-17",
|
|
51
|
+
Statement: [
|
|
52
|
+
{
|
|
53
|
+
Effect: "Deny",
|
|
54
|
+
NotAction: [
|
|
55
|
+
"iam:*",
|
|
56
|
+
"organizations:*",
|
|
57
|
+
"route53:*",
|
|
58
|
+
"cloudfront:*",
|
|
59
|
+
"sts:*",
|
|
60
|
+
"support:*",
|
|
61
|
+
"budgets:*",
|
|
62
|
+
],
|
|
63
|
+
Resource: "*",
|
|
64
|
+
Condition: { StringNotEquals: { "aws:RequestedRegion": regions } },
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The recommended foundation OU structure. Exported so callers can extend it
|
|
72
|
+
* rather than restate it.
|
|
73
|
+
*/
|
|
74
|
+
export const FOUNDATION_OUS = {
|
|
75
|
+
Security: { scps: ["deny-audit-tamper"] },
|
|
76
|
+
Infrastructure: {},
|
|
77
|
+
Sandbox: {},
|
|
78
|
+
Workloads: {},
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Author the desired-state tree an external governance reconciler applies.
|
|
82
|
+
* Pure. Throws when the tree attaches an SCP name with no definition; only
|
|
83
|
+
* SCPs the tree actually attaches are included in the output.
|
|
84
|
+
*/
|
|
85
|
+
export function landingZoneConfig(props = {}) {
|
|
86
|
+
const foundation = props.foundation ?? true;
|
|
87
|
+
const scps = {
|
|
88
|
+
...(foundation
|
|
89
|
+
? { "deny-leave-organization": DENY_LEAVE_ORGANIZATION, "deny-audit-tamper": DENY_AUDIT_TAMPER }
|
|
90
|
+
: {}),
|
|
91
|
+
...(props.allowedRegions?.length ? { "region-restriction": regionRestriction(props.allowedRegions) } : {}),
|
|
92
|
+
...props.scps,
|
|
93
|
+
};
|
|
94
|
+
const ous = { ...(foundation ? FOUNDATION_OUS : {}), ...props.ous };
|
|
95
|
+
const rootScps = [
|
|
96
|
+
...(foundation ? ["deny-leave-organization"] : []),
|
|
97
|
+
...(props.allowedRegions?.length ? ["region-restriction"] : []),
|
|
98
|
+
...(props.rootScps ?? []),
|
|
99
|
+
];
|
|
100
|
+
const attached = new Set(rootScps);
|
|
101
|
+
const collect = (tree) => {
|
|
102
|
+
for (const node of Object.values(tree)) {
|
|
103
|
+
for (const s of node.scps ?? [])
|
|
104
|
+
attached.add(s);
|
|
105
|
+
if (node.children)
|
|
106
|
+
collect(node.children);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
collect(ous);
|
|
110
|
+
for (const name of attached) {
|
|
111
|
+
if (!scps[name])
|
|
112
|
+
throw new Error(`landingZoneConfig: SCP "${name}" is attached but not defined in scps`);
|
|
113
|
+
}
|
|
114
|
+
if (props.identity) {
|
|
115
|
+
const granted = [...(props.identity.assignments ?? []), ...(props.identity.breakGlass ? [props.identity.breakGlass] : [])];
|
|
116
|
+
for (const a of granted) {
|
|
117
|
+
if (!props.identity.permissionSets[a.permissionSet]) {
|
|
118
|
+
throw new Error(`landingZoneConfig: assignment for "${a.principal}" references permission set "${a.permissionSet}" not defined in identity.permissionSets`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
organization: rootScps.length ? { scps: rootScps } : {},
|
|
124
|
+
ous,
|
|
125
|
+
scps: Object.fromEntries(Object.entries(scps).filter(([n]) => attached.has(n))),
|
|
126
|
+
...(props.identity ? { identity: props.identity } : {}),
|
|
127
|
+
...(props.cloudtrailBucket
|
|
128
|
+
? { auditSinks: { cloudtrail: { bucket: props.cloudtrailBucket, multiRegion: true } } }
|
|
129
|
+
: {}),
|
|
130
|
+
};
|
|
131
|
+
}
|
package/dist/health.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime health for AWS (#4177): Route 53 health checks and ECS services.
|
|
3
|
+
*
|
|
4
|
+
* The stack's own resource list maps each logical id (the graph's node id) to
|
|
5
|
+
* the physical id the health APIs take. A stack that does not exist yet means
|
|
6
|
+
* nothing is deployed, so every entity is absent. Any other stack failure is a
|
|
7
|
+
* hole for every entity, never `unhealthy`.
|
|
8
|
+
*
|
|
9
|
+
* - `AWS::Route53::HealthCheck`: `GetHealthCheckStatus`, aggregated as Route 53
|
|
10
|
+
* does: healthy when more than 18% of the checkers report healthy.
|
|
11
|
+
* - `AWS::ECS::Service`: `DescribeServices`, `runningCount` against
|
|
12
|
+
* `desiredCount`.
|
|
13
|
+
*
|
|
14
|
+
* Both go through the read transport's endpoint rule, so `AWS_ENDPOINT_URL`
|
|
15
|
+
* (Floci) answers them.
|
|
16
|
+
*/
|
|
17
|
+
import type { HealthEntry, HealthReadOptions, HealthReadResult } from "@intentius/chant/lexicon";
|
|
18
|
+
import { type AwsReadClientOptions } from "./api/read-client.js";
|
|
19
|
+
export declare const AWS_HEALTH_TYPES: readonly ["AWS::Route53::HealthCheck", "AWS::ECS::Service"];
|
|
20
|
+
/** Injectable HTTP for both calls, so tests never reach the network. */
|
|
21
|
+
export type AwsHealthHttp = (method: "GET" | "POST", url: string, init: {
|
|
22
|
+
headers: Record<string, string>;
|
|
23
|
+
body?: string;
|
|
24
|
+
}) => Promise<{
|
|
25
|
+
status: number;
|
|
26
|
+
text: string;
|
|
27
|
+
}>;
|
|
28
|
+
export interface AwsHealthOptions extends HealthReadOptions {
|
|
29
|
+
http?: AwsHealthHttp;
|
|
30
|
+
/** Read client for the stack list and the signing decision. Tests inject `http` and `env` here. */
|
|
31
|
+
client?: AwsReadClientOptions;
|
|
32
|
+
now?: () => Date;
|
|
33
|
+
}
|
|
34
|
+
/** One checker's report, as `GetHealthCheckStatus` returns it. */
|
|
35
|
+
export interface CheckerObservation {
|
|
36
|
+
region?: string;
|
|
37
|
+
ipAddress?: string;
|
|
38
|
+
status: string;
|
|
39
|
+
checkedTime?: string;
|
|
40
|
+
}
|
|
41
|
+
/** Parse `GetHealthCheckStatusResponse`'s observations. */
|
|
42
|
+
export declare function parseHealthCheckStatus(xml: string): CheckerObservation[];
|
|
43
|
+
/** Route 53's verdict over its checkers' observations. */
|
|
44
|
+
export declare function healthCheckEntry(observations: CheckerObservation[], observedAt: string): HealthEntry;
|
|
45
|
+
/** The parts of an ECS service `DescribeServices` returns that decide health. */
|
|
46
|
+
export interface EcsServiceState {
|
|
47
|
+
status?: string;
|
|
48
|
+
desiredCount?: number;
|
|
49
|
+
runningCount?: number;
|
|
50
|
+
pendingCount?: number;
|
|
51
|
+
deployments?: Array<{
|
|
52
|
+
rolloutState?: string;
|
|
53
|
+
updatedAt?: number | string;
|
|
54
|
+
}>;
|
|
55
|
+
}
|
|
56
|
+
/** Running against desired. Scaled to zero is `unknown`: nothing is serving, by choice. */
|
|
57
|
+
export declare function ecsServiceEntry(service: EcsServiceState, observedAt: string): HealthEntry;
|
|
58
|
+
/** The cluster a service ARN names: `service/<cluster>/<name>`, or the default cluster for the old `service/<name>` form. */
|
|
59
|
+
export declare function clusterOfServiceArn(arn: string): string;
|
|
60
|
+
export declare function observeHealthAws(options: AwsHealthOptions): Promise<HealthReadResult>;
|
|
61
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAoB,MAAM,0BAA0B,CAAC;AACnH,OAAO,EASL,KAAK,oBAAoB,EAC1B,MAAM,mBAAmB,CAAC;AAI3B,eAAO,MAAM,gBAAgB,YAAI,2BAA2B,EAAE,mBAAmB,CAAU,CAAC;AAE5F,wEAAwE;AACxE,MAAM,MAAM,aAAa,GAAG,CAC1B,MAAM,EAAE,KAAK,GAAG,MAAM,EACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KACrD,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAO/C,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,mGAAmG;IACnG,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAKD,kEAAkE;AAClE,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAcxE;AAOD,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,kBAAkB,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAepG;AAED,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7E;AAED,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAazF;AAED,6HAA6H;AAC7H,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvD;AAkED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgF3F"}
|
package/dist/health.js
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime health for AWS (#4177): Route 53 health checks and ECS services.
|
|
3
|
+
*
|
|
4
|
+
* The stack's own resource list maps each logical id (the graph's node id) to
|
|
5
|
+
* the physical id the health APIs take. A stack that does not exist yet means
|
|
6
|
+
* nothing is deployed, so every entity is absent. Any other stack failure is a
|
|
7
|
+
* hole for every entity, never `unhealthy`.
|
|
8
|
+
*
|
|
9
|
+
* - `AWS::Route53::HealthCheck`: `GetHealthCheckStatus`, aggregated as Route 53
|
|
10
|
+
* does: healthy when more than 18% of the checkers report healthy.
|
|
11
|
+
* - `AWS::ECS::Service`: `DescribeServices`, `runningCount` against
|
|
12
|
+
* `desiredCount`.
|
|
13
|
+
*
|
|
14
|
+
* Both go through the read transport's endpoint rule, so `AWS_ENDPOINT_URL`
|
|
15
|
+
* (Floci) answers them.
|
|
16
|
+
*/
|
|
17
|
+
import { AwsReadError, describeStackResources, requestHeaders, serviceUrl, withChainCredentials, withEndpointOverride, xmlError, xmlLeaves, } from "./api/read-client.js";
|
|
18
|
+
import { resolveCredentials, signRequest } from "./api/sigv4.js";
|
|
19
|
+
import { stackDoesNotExist } from "./stack-errors.js";
|
|
20
|
+
export const AWS_HEALTH_TYPES = ["AWS::Route53::HealthCheck", "AWS::ECS::Service"];
|
|
21
|
+
const defaultHttp = async (method, url, init) => {
|
|
22
|
+
const res = await fetch(url, { method, headers: init.headers, ...(init.body !== undefined ? { body: init.body } : {}) });
|
|
23
|
+
return { status: res.status, text: await res.text() };
|
|
24
|
+
};
|
|
25
|
+
/** Route 53 treats an endpoint as healthy when more than this share of checkers says so. */
|
|
26
|
+
const ROUTE53_HEALTHY_SHARE = 0.18;
|
|
27
|
+
/** Parse `GetHealthCheckStatusResponse`'s observations. */
|
|
28
|
+
export function parseHealthCheckStatus(xml) {
|
|
29
|
+
const out = [];
|
|
30
|
+
for (const m of xml.matchAll(/<HealthCheckObservation>([\s\S]*?)<\/HealthCheckObservation>/g)) {
|
|
31
|
+
const body = m[1] ?? "";
|
|
32
|
+
const report = xmlLeaves(body.match(/<StatusReport>([\s\S]*?)<\/StatusReport>/)?.[1] ?? "");
|
|
33
|
+
const top = xmlLeaves(body.replace(/<StatusReport>[\s\S]*?<\/StatusReport>/, ""));
|
|
34
|
+
out.push({
|
|
35
|
+
...(top.Region ? { region: top.Region } : {}),
|
|
36
|
+
...(top.IPAddress ? { ipAddress: top.IPAddress } : {}),
|
|
37
|
+
status: report.Status ?? "",
|
|
38
|
+
...(report.CheckedTime ? { checkedTime: report.CheckedTime } : {}),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
/** A checker's status text starts with `Success` when it found the endpoint healthy. */
|
|
44
|
+
function checkerHealthy(o) {
|
|
45
|
+
return /^success/i.test(o.status.trim());
|
|
46
|
+
}
|
|
47
|
+
/** Route 53's verdict over its checkers' observations. */
|
|
48
|
+
export function healthCheckEntry(observations, observedAt) {
|
|
49
|
+
const type = "AWS::Route53::HealthCheck";
|
|
50
|
+
if (observations.length === 0) {
|
|
51
|
+
return { type, state: "unknown", detail: "no checker has reported yet", observedAt };
|
|
52
|
+
}
|
|
53
|
+
const healthy = observations.filter(checkerHealthy).length;
|
|
54
|
+
const latest = [...observations].sort((a, b) => (b.checkedTime ?? "").localeCompare(a.checkedTime ?? ""))[0];
|
|
55
|
+
const state = healthy / observations.length > ROUTE53_HEALTHY_SHARE ? "healthy" : "unhealthy";
|
|
56
|
+
return {
|
|
57
|
+
type,
|
|
58
|
+
state,
|
|
59
|
+
detail: `${healthy}/${observations.length} checkers healthy; last: ${latest.status}`,
|
|
60
|
+
observedAt,
|
|
61
|
+
...(latest.checkedTime ? { checkedAt: latest.checkedTime } : {}),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Running against desired. Scaled to zero is `unknown`: nothing is serving, by choice. */
|
|
65
|
+
export function ecsServiceEntry(service, observedAt) {
|
|
66
|
+
const type = "AWS::ECS::Service";
|
|
67
|
+
const desired = service.desiredCount ?? 0;
|
|
68
|
+
const running = service.runningCount ?? 0;
|
|
69
|
+
const pending = service.pendingCount ?? 0;
|
|
70
|
+
const counts = `${running}/${desired} running${pending > 0 ? `, ${pending} pending` : ""}`;
|
|
71
|
+
const rollout = service.deployments?.find((d) => d.rolloutState)?.rolloutState;
|
|
72
|
+
const detail = `${counts}${rollout ? `, rollout ${rollout}` : ""}`;
|
|
73
|
+
if (service.status && service.status !== "ACTIVE") {
|
|
74
|
+
return { type, state: "unhealthy", detail: `service is ${service.status}; ${detail}`, observedAt };
|
|
75
|
+
}
|
|
76
|
+
if (desired === 0)
|
|
77
|
+
return { type, state: "unknown", detail: `desired count is 0; ${detail}`, observedAt };
|
|
78
|
+
return { type, state: running >= desired ? "healthy" : "unhealthy", detail, observedAt };
|
|
79
|
+
}
|
|
80
|
+
/** The cluster a service ARN names: `service/<cluster>/<name>`, or the default cluster for the old `service/<name>` form. */
|
|
81
|
+
export function clusterOfServiceArn(arn) {
|
|
82
|
+
const resource = arn.split(":").slice(5).join(":");
|
|
83
|
+
const parts = resource.split("/");
|
|
84
|
+
return parts.length >= 3 ? parts[1] : "default";
|
|
85
|
+
}
|
|
86
|
+
function holeFrom(type, err) {
|
|
87
|
+
const detail = err instanceof AwsReadError && err.code ? `${err.code}: ${err.message}` : err instanceof Error ? err.message : String(err);
|
|
88
|
+
const reason = /credential|token|expired|AccessDenied|not authorized|Unauthorized/i.test(detail) ? "no-credentials" : "read-failed";
|
|
89
|
+
return { type, reason, detail: detail.slice(0, 200) };
|
|
90
|
+
}
|
|
91
|
+
async function getHealthCheckStatus(id, client, http) {
|
|
92
|
+
const options = await withChainCredentials(withEndpointOverride("route53", client));
|
|
93
|
+
// Route 53 is global: one host, signed in us-east-1.
|
|
94
|
+
const base = (options.endpoint ?? "https://route53.amazonaws.com").replace(/\/$/, "");
|
|
95
|
+
const url = `${base}/2013-04-01/healthcheck/${encodeURIComponent(id)}/status`;
|
|
96
|
+
const env = options.env ?? process.env;
|
|
97
|
+
const credentials = resolveCredentials(options.credentials, env);
|
|
98
|
+
const signable = credentials && (!options.endpoint || options.signEndpointOverride === true);
|
|
99
|
+
const headers = signable
|
|
100
|
+
? signRequest({ method: "GET", url, headers: {}, body: "", service: "route53", region: "us-east-1", credentials, ...(options.now ? { now: options.now } : {}) })
|
|
101
|
+
: {};
|
|
102
|
+
const res = await http("GET", url, { headers });
|
|
103
|
+
const err = xmlError(res.text);
|
|
104
|
+
if (err || res.status >= 400) {
|
|
105
|
+
throw new AwsReadError(err?.message ?? `GetHealthCheckStatus failed with HTTP ${res.status}`, res.status, err?.code);
|
|
106
|
+
}
|
|
107
|
+
return parseHealthCheckStatus(res.text);
|
|
108
|
+
}
|
|
109
|
+
async function describeServices(cluster, arns, client, http) {
|
|
110
|
+
const options = await withChainCredentials(withEndpointOverride("ecs", client));
|
|
111
|
+
const url = serviceUrl("ecs", options.endpoint, options.region);
|
|
112
|
+
const body = JSON.stringify({ cluster, services: arns });
|
|
113
|
+
const headers = requestHeaders("ecs", url, body, { "content-type": "application/x-amz-json-1.1", "x-amz-target": "AmazonEC2ContainerServiceV20141113.DescribeServices" }, options);
|
|
114
|
+
const res = await http("POST", url, { headers, body });
|
|
115
|
+
let parsed = {};
|
|
116
|
+
try {
|
|
117
|
+
const value = JSON.parse(res.text);
|
|
118
|
+
if (value && typeof value === "object" && !Array.isArray(value))
|
|
119
|
+
parsed = value;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
throw new AwsReadError("unparseable DescribeServices response", res.status);
|
|
123
|
+
}
|
|
124
|
+
const errType = typeof parsed.__type === "string" ? parsed.__type.split("#").pop() : undefined;
|
|
125
|
+
if (errType || res.status >= 400) {
|
|
126
|
+
const message = typeof parsed.message === "string" ? parsed.message : `DescribeServices failed with HTTP ${res.status}`;
|
|
127
|
+
throw new AwsReadError(message, res.status, errType);
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
services: Array.isArray(parsed.services) ? parsed.services : [],
|
|
131
|
+
failures: Array.isArray(parsed.failures) ? parsed.failures : [],
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
export async function observeHealthAws(options) {
|
|
135
|
+
const http = options.http ?? defaultHttp;
|
|
136
|
+
const observedAt = (options.now?.() ?? new Date()).toISOString();
|
|
137
|
+
const client = { ...(options.client ?? {}), ...(options.region ? { region: options.region } : {}) };
|
|
138
|
+
const entities = {};
|
|
139
|
+
const unobserved = {};
|
|
140
|
+
const absent = [];
|
|
141
|
+
if (options.entities.size === 0)
|
|
142
|
+
return { entities, unobserved, absent };
|
|
143
|
+
const stackName = options.stack ?? options.environment;
|
|
144
|
+
let physical;
|
|
145
|
+
try {
|
|
146
|
+
const resources = await describeStackResources(stackName, client);
|
|
147
|
+
physical = new Map(resources.filter((r) => r.physicalId).map((r) => [r.logicalId, r.physicalId]));
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
if (err instanceof AwsReadError && stackDoesNotExist(err.message))
|
|
151
|
+
return { entities, unobserved, absent: [...options.entities.keys()] };
|
|
152
|
+
for (const [name, { entityType }] of options.entities) {
|
|
153
|
+
unobserved[name] = holeFrom(entityType, err);
|
|
154
|
+
unobserved[name].detail = `DescribeStackResources failed for stack "${stackName}": ${unobserved[name].detail}`;
|
|
155
|
+
}
|
|
156
|
+
return { entities, unobserved, absent };
|
|
157
|
+
}
|
|
158
|
+
const services = new Map();
|
|
159
|
+
const checks = [];
|
|
160
|
+
for (const [name, { entityType }] of options.entities) {
|
|
161
|
+
const id = physical.get(name);
|
|
162
|
+
if (!id) {
|
|
163
|
+
absent.push(name);
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (entityType === "AWS::ECS::Service") {
|
|
167
|
+
const cluster = clusterOfServiceArn(id);
|
|
168
|
+
const list = services.get(cluster) ?? [];
|
|
169
|
+
list.push({ name, arn: id });
|
|
170
|
+
services.set(cluster, list);
|
|
171
|
+
}
|
|
172
|
+
else if (entityType === "AWS::Route53::HealthCheck") {
|
|
173
|
+
checks.push({ name, id });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
await Promise.all(checks.map(async ({ name, id }) => {
|
|
177
|
+
try {
|
|
178
|
+
entities[name] = healthCheckEntry(await getHealthCheckStatus(id, client, http), observedAt);
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
if (err instanceof AwsReadError && err.code === "NoSuchHealthCheck")
|
|
182
|
+
absent.push(name);
|
|
183
|
+
else
|
|
184
|
+
unobserved[name] = holeFrom("AWS::Route53::HealthCheck", err);
|
|
185
|
+
}
|
|
186
|
+
}));
|
|
187
|
+
await Promise.all([...services].map(async ([cluster, members]) => {
|
|
188
|
+
// DescribeServices takes at most ten services per call.
|
|
189
|
+
for (let i = 0; i < members.length; i += 10) {
|
|
190
|
+
const batch = members.slice(i, i + 10);
|
|
191
|
+
try {
|
|
192
|
+
const { services: found, failures } = await describeServices(cluster, batch.map((m) => m.arn), client, http);
|
|
193
|
+
for (const member of batch) {
|
|
194
|
+
const service = found.find((s) => s.serviceArn === member.arn || s.serviceArn?.endsWith(`/${member.arn.split("/").pop()}`));
|
|
195
|
+
const failure = failures.find((f) => f.arn === member.arn);
|
|
196
|
+
if (service)
|
|
197
|
+
entities[member.name] = ecsServiceEntry(service, observedAt);
|
|
198
|
+
else if (failure?.reason === "MISSING")
|
|
199
|
+
absent.push(member.name);
|
|
200
|
+
else {
|
|
201
|
+
unobserved[member.name] = {
|
|
202
|
+
type: "AWS::ECS::Service",
|
|
203
|
+
reason: "read-failed",
|
|
204
|
+
detail: failure?.reason ? `DescribeServices: ${failure.reason}` : "DescribeServices did not return the service",
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
for (const member of batch)
|
|
211
|
+
unobserved[member.name] = holeFrom("AWS::ECS::Service", err);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}));
|
|
215
|
+
return { entities, unobserved, absent };
|
|
216
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity-observe.d.ts","sourceRoot":"","sources":["../src/identity-observe.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"identity-observe.d.ts","sourceRoot":"","sources":["../src/identity-observe.ts"],"names":[],"mappings":"AAyBA,OAAO,EAA4C,KAAK,oBAAoB,EAAgC,MAAM,mBAAmB,CAAC;AACtI,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAmBjE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAazG;AAkCD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EAAE,EACrB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,GAAG,SAAS,EACzF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,EACzC,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CA4B3F"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The identity fallback on the stack read (#1647).
|
|
3
|
+
*
|
|
4
|
+
* `describeResources` asks CloudFormation exactly one question — is there a
|
|
5
|
+
* logical id named <entity> in this stack? — which reads a freshly
|
|
6
|
+
* carve-emitted, still-Terraform-owned resource as confirmed-absent even
|
|
7
|
+
* though the declared `BucketName` names it precisely. When a declared entity
|
|
8
|
+
* is absent from the stack AND its props spell the type's full primary
|
|
9
|
+
* identifier (the spec knowledge the codegen already compiled into
|
|
10
|
+
* `lexicon-aws.json`), ask Cloud Control for it by identity. Found means
|
|
11
|
+
* OBSERVED: `ownership: "foreign"` (it exists and something other than this
|
|
12
|
+
* stack owns it — Terraform, a console hand, another tool) and
|
|
13
|
+
* `status: "EXTERNAL"` (live outside the stack, deliberately not a
|
|
14
|
+
* CloudFormation status word).
|
|
15
|
+
*
|
|
16
|
+
* Best-effort ON TOP of a stack answer, never instead of one: a genuine miss
|
|
17
|
+
* (`ResourceNotFoundException`) keeps the stack's absent verdict, and so does
|
|
18
|
+
* every other refusal (`UnsupportedOperation` — a Floci without Cloud
|
|
19
|
+
* Control — credentials, throttling). The stack read succeeded; absence at
|
|
20
|
+
* stack scope is an honest verdict this fallback can refine but must never
|
|
21
|
+
* degrade into a hole, or a pre-first-apply plan would stop proposing
|
|
22
|
+
* `create` the moment the emulator lacks Cloud Control.
|
|
23
|
+
*/
|
|
24
|
+
import { createRequire } from "module";
|
|
25
|
+
import { moduleSourceUrl } from "@intentius/chant/module-source";
|
|
26
|
+
import { AwsReadError, getResource, listResources } from "./api/read-client.js";
|
|
27
|
+
const require = createRequire(moduleSourceUrl(import.meta.url));
|
|
28
|
+
let byResourceType;
|
|
29
|
+
function manifestByType() {
|
|
30
|
+
if (!byResourceType) {
|
|
31
|
+
const manifest = require("./generated/lexicon-aws.json");
|
|
32
|
+
byResourceType = new Map(Object.values(manifest).map((e) => [e.resourceType, e]));
|
|
33
|
+
}
|
|
34
|
+
return byResourceType;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The Cloud Control identifier the declared props spell, or undefined when the
|
|
38
|
+
* type has no primary identifier on record or any part of it is absent or
|
|
39
|
+
* non-scalar (a Ref, an intrinsic, a server-assigned name). Multi-part
|
|
40
|
+
* identifiers join with `|`, Cloud Control's own separator.
|
|
41
|
+
*/
|
|
42
|
+
export function declaredIdentifier(entityType, props) {
|
|
43
|
+
const entry = manifestByType().get(entityType);
|
|
44
|
+
const parts = entry?.primaryIdentifier;
|
|
45
|
+
if (!entry || entry.kind !== "resource" || !parts || parts.length === 0)
|
|
46
|
+
return undefined;
|
|
47
|
+
const values = [];
|
|
48
|
+
for (const part of parts) {
|
|
49
|
+
const v = props[part];
|
|
50
|
+
if (typeof v !== "string" && typeof v !== "number")
|
|
51
|
+
return undefined;
|
|
52
|
+
const s = String(v);
|
|
53
|
+
if (!s)
|
|
54
|
+
return undefined;
|
|
55
|
+
values.push(s);
|
|
56
|
+
}
|
|
57
|
+
return values.join("|");
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* `GetResource`, with a `ListResources` + identifier-match fallback when the
|
|
61
|
+
* endpoint says the operation itself is unsupported. That is Floci's exact
|
|
62
|
+
* answer (read-client's own note) while it serves `ListResources` fine — and
|
|
63
|
+
* an emulator is exactly where the carve state lives, so without this leg the
|
|
64
|
+
* fallback proves itself everywhere except the one place the walkthrough
|
|
65
|
+
* films it. Every other refusal propagates: the caller decides what a failed
|
|
66
|
+
* refinement means.
|
|
67
|
+
*/
|
|
68
|
+
async function readByIdentity(typeName, identifier, client) {
|
|
69
|
+
try {
|
|
70
|
+
return await getResource(typeName, identifier, client);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
if (!(err instanceof AwsReadError) || err.code !== "UnsupportedOperation")
|
|
74
|
+
throw err;
|
|
75
|
+
const listed = await listResources(typeName, client);
|
|
76
|
+
return listed.find((d) => d.identifier === identifier) ?? null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/** The same scrub the stack-output path applies, on live property KEYS. */
|
|
80
|
+
function redactSensitive(properties) {
|
|
81
|
+
const out = {};
|
|
82
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
83
|
+
out[key] = /password|secret|token/i.test(key) ? "[REDACTED]" : value;
|
|
84
|
+
}
|
|
85
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Identity-read every entity the stack did not answer for and whose props
|
|
89
|
+
* spell an identifier. `already` is the stack's answer — an entity the stack
|
|
90
|
+
* DID return is never re-read. The `queried` map records the address each
|
|
91
|
+
* attempted read was issued against (#1620), whatever the verdict.
|
|
92
|
+
*/
|
|
93
|
+
export async function observeByIdentity(entityNames, entities, already, client) {
|
|
94
|
+
const resources = {};
|
|
95
|
+
const queried = {};
|
|
96
|
+
if (!entities)
|
|
97
|
+
return { resources, queried };
|
|
98
|
+
for (const name of entityNames) {
|
|
99
|
+
if (already[name])
|
|
100
|
+
continue;
|
|
101
|
+
const entity = entities.get(name);
|
|
102
|
+
if (!entity)
|
|
103
|
+
continue;
|
|
104
|
+
const identifier = declaredIdentifier(entity.entityType, entity.props ?? {});
|
|
105
|
+
if (!identifier)
|
|
106
|
+
continue;
|
|
107
|
+
queried[name] = `cloudcontrol:GetResource:${entity.entityType}:${identifier}`;
|
|
108
|
+
try {
|
|
109
|
+
const found = await readByIdentity(entity.entityType, identifier, client);
|
|
110
|
+
if (!found)
|
|
111
|
+
continue;
|
|
112
|
+
resources[name] = {
|
|
113
|
+
type: entity.entityType,
|
|
114
|
+
physicalId: found.identifier || identifier,
|
|
115
|
+
status: "EXTERNAL",
|
|
116
|
+
ownership: "foreign",
|
|
117
|
+
...(redactSensitive(found.properties) ? { attributes: redactSensitive(found.properties) } : {}),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Refusals of every kind keep the stack's verdict — see the module
|
|
122
|
+
// comment for why a failed refinement must not become a hole.
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return { resources, queried };
|
|
127
|
+
}
|