@go-to-k/cdkd 0.299.8 → 0.300.1
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/{asg-provider-ebjf5E8o.js → asg-provider-BS5i71bK.js} +3 -3
- package/dist/{asg-provider-ebjf5E8o.js.map → asg-provider-BS5i71bK.js.map} +1 -1
- package/dist/{aws-clients-Bj7qH5Ph.js → aws-clients-B_CEQGE1.js} +21 -1
- package/dist/aws-clients-B_CEQGE1.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-BU3iY59A.js → deploy-engine-BK4gG_5A.js} +734 -80
- package/dist/deploy-engine-BK4gG_5A.js.map +1 -0
- package/dist/{iam-policy-targets-dAY3-gXJ.js → iam-policy-targets-DAs3w7QW.js} +47 -6
- package/dist/{iam-policy-targets-dAY3-gXJ.js.map → iam-policy-targets-DAs3w7QW.js.map} +1 -1
- package/dist/{iam-role-provider-C8O3q2ua.js → iam-role-provider-SmvPHPLC.js} +16 -11
- package/dist/iam-role-provider-SmvPHPLC.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/{neptune-provider-CuJF3t-Q.js → neptune-provider-CqZ1FaqT.js} +3 -3
- package/dist/{neptune-provider-CuJF3t-Q.js.map → neptune-provider-CqZ1FaqT.js.map} +1 -1
- package/dist/{program-C87Q8YFK.js → program-DVPHKsxv.js} +668 -512
- package/dist/program-DVPHKsxv.js.map +1 -0
- package/dist/{provider-classes-DmohfhIq.js → provider-classes-CDzT2xg0.js} +1433 -158
- package/dist/provider-classes-CDzT2xg0.js.map +1 -0
- package/dist/{rds-provider-Br3hPyHP.js → rds-provider-DraxDuQq.js} +13 -7
- package/dist/rds-provider-DraxDuQq.js.map +1 -0
- package/dist/{version-BtTEjOpj.js → version-DTSDiQcV.js} +2 -2
- package/dist/{version-BtTEjOpj.js.map → version-DTSDiQcV.js.map} +1 -1
- package/package.json +3 -1
- package/dist/aws-clients-Bj7qH5Ph.js.map +0 -1
- package/dist/deploy-engine-BU3iY59A.js.map +0 -1
- package/dist/iam-role-provider-C8O3q2ua.js.map +0 -1
- package/dist/program-C87Q8YFK.js.map +0 -1
- package/dist/provider-classes-DmohfhIq.js.map +0 -1
- package/dist/rds-provider-Br3hPyHP.js.map +0 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { r as getAwsClients } from "./aws-clients-
|
|
1
|
+
import { r as getAwsClients } from "./aws-clients-B_CEQGE1.js";
|
|
2
2
|
import { B as safeMsg, F as displaySafe, I as displayStackName, L as isPasteableIdent, O as SECRET_REF_MAX_CODE_POINTS, P as displayIdent, a as getLogger, b as generateResourceNameWithFallback, n as isAwsAuthoredFailure, r as safeStringify, t as describeAwsFailure, y as generateResourceName, z as plainIdentOr } from "./aws-failure-text-BEQfs6za.js";
|
|
3
|
-
import { $ as protectedReplacementAdvice, $
|
|
3
|
+
import { $ as protectedReplacementAdvice, $t as ambientCredentialConfig, A as isQuotableImportValue, B as isTerminalDeleteFailure, C as setBounded, D as VALUE_NOT_SHOWN, E as assertRegionMatch, F as resolveExplicitPhysicalId, Fn as isInertUnquoted, H as observeThenDisableProtection, Hn as withheldTargetClause, In as pasteableCommand, Kt as injectiveKey, L as ProtectionFlipRegistry, M as quotedRemedyLogicalId, Mt as markCreatedBeforeFailure, N as refusalTypeShown, Nn as commandHole, Nt as markSupersedesEarlierCreate, O as isPlainImportJson, P as remedyLogicalId, Pn as hasClauseBreak, Q as pasteableAwsCommand, Qn as markReplayMayCollide, Qt as ambientClientDefaults, Rn as plainOrDescribed, S as replayedSendWindow, St as withDerivedNameMasks, T as RESOURCE_NOT_FOUND, Tt as clearCreatedBeforeFailure, U as protectionFlipKey, V as logGroupProtectionSite, Vn as shellQuote, W as rdsFamilyProtectionSite, X as WITHHELD_AWS_COMMAND, Y as UNNAMEABLE_ID_CLAUSE, Z as isAwsCliLiteral, Zn as markNameCollision, Zt as withPasteableAwsProfile, _ as RecentIdSet, _t as createMaskedLogSinks, a as onlySecretDerived, at as startInterruptWatch, b as isInsideWindow, bn as ResourceUpdateNotSupportedError, bt as maskDeep, c as recordedPrincipalsRepair, cr as isThrottlingError, ct as canonicalizeRoute53QueryName, dr as wrapMaskedAwsError, dt as compositeIdSkipResult, en as clientDefaultsFor, et as renderDisableCommand, ft as logicalIdShown, g as AmbiguousCreateLatch, gt as stateOrphanRecordRemedy, h as AMBIGUOUS_LATCH_TTL_MS, ht as segmentAfterAnchor, i as holdsSecretDerivedEntry, in as CdkdError, ir as isTransientServerError, it as isInterruptedWaitError, j as normalizeAwsTagsToCfn, jt as markAuxiliaryFailure, k as isPlainImportValue, lr as markNonRetryable, lt as compositeIdFormatMessage, nn as AccountIdUnavailableError, o as readPrincipalLists, or as THROTTLING_ERROR_NAMES, ot as ElapsedBudgetRegistry, p as withRemovalDefaults, pt as packCompositeId, q as userPoolProtectionSite, qt as injectiveKeyPrefix, r as SECRET_DERIVED_READ_LIVE, rr as isRetryableTransientError, sr as isMarkedNonRetryable, tn as credentialFingerprint, tr as isAmbiguousOutcomeError, u as clearOnUpdateRemoval, ur as markRedactedCause, ut as compositeIdSeparatorRefusal, v as ambiguousAttemptLead, vn as ProvisioningError, vt as createMaskedRetryLogger, w as withoutServerErrorRetries, x as replayFollowedAmbiguousAttempt, xt as maskerOrIdentity, y as createAttemptKey, yt as isSecretDerivedValue, z as deleteWithProtectionCompensation } from "./iam-policy-targets-DAs3w7QW.js";
|
|
4
4
|
import { s as ambientRegion } from "./aws-client-defaults-DBXBcg0J.js";
|
|
5
|
-
import { $ as S3_AUTO_DELETE_OBJECTS_TAG, Ao as
|
|
6
|
-
import { n as collectInlinePolicyNamesManagedBySiblings, r as IamCreateClientCache, t as IAMRoleProvider } from "./iam-role-provider-
|
|
7
|
-
import { a as resolveSecretDerivedPrincipals, i as isResolvableSecretPrincipalList, n as runDestroyForStack, o as canonicalizeIpProtocolValue, r as holdsUnprovenSecretPrincipalToken, s as resolvedResourceTimeoutMs, t as canonicalizeIpv4Cidr } from "./program-
|
|
8
|
-
import { RDSProvider } from "./rds-provider-
|
|
9
|
-
import { NeptuneProvider } from "./neptune-provider-
|
|
10
|
-
import { ASGProvider } from "./asg-provider-
|
|
5
|
+
import { $ as S3_AUTO_DELETE_OBJECTS_TAG, $a as withheldAccountClause, Ao as withRetry, At as withNestedStackContext, Br as markWaitAbandoned, Bt as awaitInFlightSibling, C as withApiLimit, Co as replayWarn, Ei as getAccountInfo, Eo as requireConfigString, Es as recordAttributeIdCopy, Fl as describeFileReadFailure, G as deleteBudgetKey, Go as passedNoEchoParametersOf, Gr as reDisableInstanceApiTermination, Gt as replacedDeleteFailureVerdict, H as DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS, Hr as ec2InstanceProtectionSite, Ht as getStackRecords, Ii as parseWebACLArn, Il as displayAssemblyPath, J as DELETE_INDEX_WAIT_PROCEED_NOTE, K as resolveDynamoDbDeleteBudgetClock, Ki as accountArgs, Kr as reEnableInstanceApiTermination, Ll as renderAssemblyPathEscape, Lr as deleteSkipReason, Mo as lambdaFunctionNameForMask, Mr as unchangedBehindSecretReference, No as sameLambdaFunctionAddress, Q as ECR_AUTO_DELETE_IMAGES_TAG, Qo as hasMaskableValues, Rl as resolveAssemblyPath, Rr as withIndeterminateGuard, S as lookupEachName, So as readConfigString, St as getNestedRevertRun, Tl as derivePartitionAndUrlSuffix, To as requireConfigObject, Tr as getCurrentResourceSecrets, Ts as physicalNameCopiesOf, Tt as revertNestedChildFromJournal, U as beginDeleteWait, Ur as isTerminationProtectionPropagationError, V as DynamoDBGlobalTableProvider, Va as refuseMalformedResourcesForDestroy, W as compensateRemovedDeletionProtection, Wr as observeThenDisableInstanceApiTermination, X as deleteTableWithIndexBusyRetry, Y as INDEX_SETTLE_POLL_INTERVAL_MS, Z as waitForIndexesSettled, _i as s3BucketRegionalDomainName, _o as coerceCfnBoolean, an as getCurrentProducerRegions, ar as acquireIdempotencyToken, b as chunks, bo as configIntegerRefusal, c as isAbsoluteAssetPath, cn as isRedactedRecordedValue, cr as DBPROXY_TAGS_WHAT, di as outputReferenceProvenanceOf, dr as readTagList, ds as recordReferenceProvenanceEntry, et as hasCdkAutoDeleteTag, fo as WARM_THROUGHPUT_MEMBERS, fr as refuseMalformedDesiredTags, fs as snapshotPassProvenance, gi as s3BucketDualStackDomainName, go as toFiniteNumber, gr as stringifyIfAssigned, gs as withoutPhysicalNameCopies, hi as s3BucketDomainName, ho as toCfnInteger, hr as definedAttributes, jo as canonicalLambdaFunctionName, jr as slowCcOperationTimeoutMs, ks as carriesSecretMask, kt as getCurrentNestedStackContext, l as listNestedTemplateRows, li as isSettledInstanceState, ln as redactedDeleteAddressFields, lr as DBPROXY_TAG_OPTIONS, mc as stringifyValue, mi as s3BucketArn, mo as isWarmThroughputDecrease, mr as tagPlanWarning, nt as getPriorAttempts, or as isRefusedByName, po as coerceWarmThroughput$1, pr as tagMapAsList, ps as redactSecretsForState, q as resolveDynamoDbDeleteBudgetMs, ro as withoutSilentDropProperties, rr as reserveStackCreateToken, rt as markRefusedBeforeApplying, s as findNestedTemplateTreeDefect, sn as REDACTED_DELETE_ADDRESS_SKIP_REASON, sr as markDeleteStarted, t as DeployEngine, to as findSilentDropProperties, tr as earliestDefined, tt as isTruthyCfnBoolean, u as renderNestedTemplateTreeDefect, un as redactedDeleteAddressSkip, ur as planTagDiff, us as markSameGenerationBag, vi as s3BucketWebsiteUrl, vo as coerceCfnInteger, vs as dynamicReferenceTokens, wl as canonicalizeRegion, wo as requireConfigArray, ws as recoverMaskedOutput, x as isAccessDeniedError, xa as refuseMalformedNestedChildOutputs, xl as decodeListingKey, xo as configStringRefusal, yc as rewriteTemplateAssetReferences, yo as configBooleanRefusal, zi as passedParameterClassesOf, zr as isWaitAbandonedError } from "./deploy-engine-BK4gG_5A.js";
|
|
6
|
+
import { n as collectInlinePolicyNamesManagedBySiblings, r as IamCreateClientCache, t as IAMRoleProvider } from "./iam-role-provider-SmvPHPLC.js";
|
|
7
|
+
import { a as resolveSecretDerivedPrincipals, i as isResolvableSecretPrincipalList, n as runDestroyForStack, o as canonicalizeIpProtocolValue, r as holdsUnprovenSecretPrincipalToken, s as resolvedResourceTimeoutMs, t as canonicalizeIpv4Cidr } from "./program-DVPHKsxv.js";
|
|
8
|
+
import { RDSProvider } from "./rds-provider-DraxDuQq.js";
|
|
9
|
+
import { NeptuneProvider } from "./neptune-provider-CqZ1FaqT.js";
|
|
10
|
+
import { ASGProvider } from "./asg-provider-BS5i71bK.js";
|
|
11
11
|
import { createHash, randomUUID } from "node:crypto";
|
|
12
12
|
import { CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListBucketsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client } from "@aws-sdk/client-s3";
|
|
13
13
|
import { AddRoleToInstanceProfileCommand, AddUserToGroupCommand, AttachGroupPolicyCommand, AttachRolePolicyCommand, AttachUserPolicyCommand, CreateAccessKeyCommand, CreateGroupCommand, CreateInstanceProfileCommand, CreateLoginProfileCommand, CreatePolicyCommand, CreatePolicyVersionCommand, CreateUserCommand, DeleteAccessKeyCommand, DeleteGroupCommand, DeleteGroupPolicyCommand, DeleteInstanceProfileCommand, DeleteLoginProfileCommand, DeletePolicyCommand, DeletePolicyVersionCommand, DeleteRolePolicyCommand, DeleteUserCommand, DeleteUserPermissionsBoundaryCommand, DeleteUserPolicyCommand, DetachGroupPolicyCommand, DetachRolePolicyCommand, DetachUserPolicyCommand, GetAccessKeyLastUsedCommand, GetGroupCommand, GetGroupPolicyCommand, GetInstanceProfileCommand, GetPolicyCommand, GetPolicyVersionCommand, GetRolePolicyCommand, GetUserCommand, GetUserPolicyCommand, IAMClient, ListAccessKeysCommand, ListAttachedGroupPoliciesCommand, ListAttachedUserPoliciesCommand, ListEntitiesForPolicyCommand, ListGroupPoliciesCommand, ListGroupsForUserCommand, ListPoliciesCommand, ListPolicyTagsCommand, ListPolicyVersionsCommand, ListUserPoliciesCommand, NoSuchEntityException, PutGroupPolicyCommand, PutRolePolicyCommand, PutUserPermissionsBoundaryCommand, PutUserPolicyCommand, RemoveRoleFromInstanceProfileCommand, RemoveUserFromGroupCommand, TagPolicyCommand, TagUserCommand, UntagPolicyCommand, UntagUserCommand, UpdateAccessKeyCommand, UpdateLoginProfileCommand } from "@aws-sdk/client-iam";
|
|
@@ -28,6 +28,8 @@ import { BedrockAgentCoreControlClient, CreateAgentRuntimeCommand, CreateEvaluat
|
|
|
28
28
|
import { AddTagsToResourceCommand as AddTagsToResourceCommand$1, CreateCacheClusterCommand, CreateCacheSubnetGroupCommand, DeleteCacheClusterCommand, DeleteCacheSubnetGroupCommand, DescribeCacheClustersCommand, DescribeCacheSubnetGroupsCommand, ElastiCacheClient, ListTagsForResourceCommand as ListTagsForResourceCommand$7, ModifyCacheClusterCommand, ModifyCacheSubnetGroupCommand, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$1 } from "@aws-sdk/client-elasticache";
|
|
29
29
|
import { ACMClient, AddTagsToCertificateCommand, DeleteCertificateCommand, DescribeCertificateCommand, ListTagsForCertificateCommand, RemoveTagsFromCertificateCommand, RequestCertificateCommand, ResourceNotFoundException as ResourceNotFoundException$7, UpdateCertificateOptionsCommand } from "@aws-sdk/client-acm";
|
|
30
30
|
import { CreateMicrovmImageCommand, DeleteMicrovmImageCommand, GetMicrovmImageCommand, LambdaMicrovmsClient, ListTagsCommand as ListTagsCommand$1, ResourceNotFoundException as ResourceNotFoundException$8, TagResourceCommand as TagResourceCommand$10, UntagResourceCommand as UntagResourceCommand$10, UpdateMicrovmImageCommand } from "@aws-sdk/client-lambda-microvms";
|
|
31
|
+
import { CreateWebFunctionEndpointCommand, CreateWebFunctionRevisionCommand, DeleteWebFunctionEndpointCommand, DeleteWebFunctionRevisionCommand, GetWebFunctionEndpointCommand, GetWebFunctionRevisionCommand, LambdaWebClient, ListWebFunctionRevisionsCommand, ResourceNotFoundException as ResourceNotFoundException$9, UpdateWebFunctionEndpointCommand } from "@aws-sdk/client-lambda-web";
|
|
32
|
+
import { CreateNetworkConnectorCommand, DeleteNetworkConnectorCommand, GetNetworkConnectorCommand, LambdaCoreClient, ResourceNotFoundException as ResourceNotFoundException$10, UpdateNetworkConnectorCommand } from "@aws-sdk/client-lambda-core";
|
|
31
33
|
import * as fs from "node:fs";
|
|
32
34
|
import * as path from "node:path";
|
|
33
35
|
import { AssociateVPCWithHostedZoneCommand, ChangeResourceRecordSetsCommand, ChangeTagsForResourceCommand, CreateHostedZoneCommand, CreateQueryLoggingConfigCommand, DeleteHostedZoneCommand, DeleteQueryLoggingConfigCommand, DisassociateVPCFromHostedZoneCommand, GetHostedZoneCommand, HostedZoneAlreadyExists, ListHostedZonesByNameCommand, ListQueryLoggingConfigsCommand, ListResourceRecordSetsCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$8, Route53Client, UpdateHostedZoneCommentCommand, UpdateHostedZoneFeaturesCommand } from "@aws-sdk/client-route-53";
|
|
@@ -42,22 +44,22 @@ import { CreateStateMachineCommand, DeleteStateMachineCommand, DescribeStateMach
|
|
|
42
44
|
import { CreateClusterCommand, CreateServiceCommand, DeleteClusterCommand, DeleteServiceCommand, DeregisterTaskDefinitionCommand, DescribeClustersCommand, DescribeServicesCommand, DescribeTaskDefinitionCommand, ECSClient, ListTaskDefinitionsCommand, PutClusterCapacityProvidersCommand, RegisterTaskDefinitionCommand, TagResourceCommand as TagResourceCommand$14, UntagResourceCommand as UntagResourceCommand$14, UpdateClusterCommand, UpdateServiceCommand, waitUntilServicesStable } from "@aws-sdk/client-ecs";
|
|
43
45
|
import { AddTagsToResourceCommand as AddTagsToResourceCommand$3, CreateDBClusterCommand as CreateDBClusterCommand$1, CreateDBInstanceCommand as CreateDBInstanceCommand$1, CreateDBSubnetGroupCommand as CreateDBSubnetGroupCommand$1, DeleteDBClusterCommand as DeleteDBClusterCommand$1, DeleteDBInstanceCommand as DeleteDBInstanceCommand$1, DeleteDBSubnetGroupCommand as DeleteDBSubnetGroupCommand$1, DescribeDBClustersCommand as DescribeDBClustersCommand$1, DescribeDBInstancesCommand as DescribeDBInstancesCommand$1, DescribeDBSubnetGroupsCommand as DescribeDBSubnetGroupsCommand$1, DocDBClient, ListTagsForResourceCommand as ListTagsForResourceCommand$12, ModifyDBClusterCommand as ModifyDBClusterCommand$1, ModifyDBInstanceCommand as ModifyDBInstanceCommand$1, ModifyDBSubnetGroupCommand as ModifyDBSubnetGroupCommand$1, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$3 } from "@aws-sdk/client-docdb";
|
|
44
46
|
import { CreateWebACLCommand, DeleteWebACLCommand, GetWebACLCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$13, TagResourceCommand as TagResourceCommand$15, UntagResourceCommand as UntagResourceCommand$15, UpdateWebACLCommand, WAFNonexistentItemException, WAFV2Client } from "@aws-sdk/client-wafv2";
|
|
45
|
-
import { AddCustomAttributesCommand, CognitoIdentityProviderClient, CreateUserPoolCommand, DeleteUserPoolCommand, DescribeUserPoolCommand, GetUserPoolMfaConfigCommand, ListUserPoolsCommand, ResourceNotFoundException as ResourceNotFoundException$
|
|
47
|
+
import { AddCustomAttributesCommand, CognitoIdentityProviderClient, CreateUserPoolCommand, DeleteUserPoolCommand, DescribeUserPoolCommand, GetUserPoolMfaConfigCommand, ListUserPoolsCommand, ResourceNotFoundException as ResourceNotFoundException$11, SetUserPoolMfaConfigCommand, UpdateUserPoolCommand } from "@aws-sdk/client-cognito-identity-provider";
|
|
46
48
|
import { CreateHttpNamespaceCommand, CreatePrivateDnsNamespaceCommand, CreatePublicDnsNamespaceCommand, CreateServiceCommand as CreateServiceCommand$1, DeleteNamespaceCommand, DeleteServiceAttributesCommand, DeleteServiceCommand as DeleteServiceCommand$1, GetNamespaceCommand, GetOperationCommand, GetServiceAttributesCommand, GetServiceCommand, ListNamespacesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$14, NamespaceNotFound, ResourceInUse, ServiceDiscoveryClient, ServiceNotFound, TagResourceCommand as TagResourceCommand$16, UntagResourceCommand as UntagResourceCommand$16, UpdateHttpNamespaceCommand, UpdatePrivateDnsNamespaceCommand, UpdatePublicDnsNamespaceCommand, UpdateServiceAttributesCommand, UpdateServiceCommand as UpdateServiceCommand$1 } from "@aws-sdk/client-servicediscovery";
|
|
47
49
|
import { AppSyncClient, CreateApiKeyCommand, CreateDataSourceCommand, CreateGraphqlApiCommand, CreateResolverCommand, DeleteApiKeyCommand, DeleteDataSourceCommand, DeleteGraphqlApiCommand, DeleteResolverCommand, GetDataSourceCommand, GetGraphqlApiCommand, GetGraphqlApiEnvironmentVariablesCommand, GetIntrospectionSchemaCommand, GetResolverCommand, ListApiKeysCommand, ListGraphqlApisCommand, NotFoundException as NotFoundException$4, PutGraphqlApiEnvironmentVariablesCommand, StartSchemaCreationCommand, TagResourceCommand as TagResourceCommand$17, UntagResourceCommand as UntagResourceCommand$17, UpdateApiKeyCommand, UpdateDataSourceCommand, UpdateGraphqlApiCommand, UpdateResolverCommand } from "@aws-sdk/client-appsync";
|
|
48
50
|
import { ConcurrentModificationException, CrawlerRunningException, CreateConnectionCommand, CreateCrawlerCommand, CreateDatabaseCommand, CreateJobCommand, CreateSecurityConfigurationCommand, CreateTableCommand as CreateTableCommand$1, CreateTriggerCommand, CreateWorkflowCommand, DeleteConnectionCommand, DeleteCrawlerCommand, DeleteDatabaseCommand, DeleteJobCommand, DeleteSecurityConfigurationCommand, DeleteTableCommand as DeleteTableCommand$1, DeleteTriggerCommand, DeleteWorkflowCommand, EntityNotFoundException, GetConnectionCommand, GetCrawlerCommand, GetDatabaseCommand, GetJobCommand, GetSecurityConfigurationCommand, GetTableCommand, GetTagsCommand, GetTriggerCommand, GetWorkflowCommand, GlueClient, StartCrawlerScheduleCommand, StartTriggerCommand, StopCrawlerCommand, StopCrawlerScheduleCommand, StopTriggerCommand, TagResourceCommand as TagResourceCommand$18, UntagResourceCommand as UntagResourceCommand$18, UpdateConnectionCommand, UpdateCrawlerCommand, UpdateDatabaseCommand, UpdateJobCommand, UpdateTableCommand as UpdateTableCommand$1, UpdateTriggerCommand, UpdateWorkflowCommand } from "@aws-sdk/client-glue";
|
|
49
51
|
import { BudgetsClient, CreateBudgetCommand, CreateNotificationCommand, CreateSubscriberCommand, DeleteBudgetCommand, DeleteNotificationCommand, DeleteSubscriberCommand, DescribeBudgetCommand, DuplicateRecordException, NotFoundException as NotFoundException$5, TagResourceCommand as TagResourceCommand$19, UntagResourceCommand as UntagResourceCommand$19, UpdateBudgetCommand } from "@aws-sdk/client-budgets";
|
|
50
|
-
import { AddTagsToStreamCommand, CreateStreamCommand, DecreaseStreamRetentionPeriodCommand, DeleteStreamCommand, DeregisterStreamConsumerCommand, DescribeStreamCommand, DescribeStreamConsumerCommand, DescribeStreamSummaryCommand, DisableEnhancedMonitoringCommand, EnableEnhancedMonitoringCommand, IncreaseStreamRetentionPeriodCommand, KinesisClient, ListTagsForResourceCommand as ListTagsForResourceCommand$15, ListTagsForStreamCommand, RegisterStreamConsumerCommand, RemoveTagsFromStreamCommand, ResourceNotFoundException as ResourceNotFoundException$
|
|
51
|
-
import { CreateScheduleCommand, DeleteScheduleCommand, GetScheduleCommand, ListSchedulesCommand, ResourceNotFoundException as ResourceNotFoundException$
|
|
52
|
+
import { AddTagsToStreamCommand, CreateStreamCommand, DecreaseStreamRetentionPeriodCommand, DeleteStreamCommand, DeregisterStreamConsumerCommand, DescribeStreamCommand, DescribeStreamConsumerCommand, DescribeStreamSummaryCommand, DisableEnhancedMonitoringCommand, EnableEnhancedMonitoringCommand, IncreaseStreamRetentionPeriodCommand, KinesisClient, ListTagsForResourceCommand as ListTagsForResourceCommand$15, ListTagsForStreamCommand, RegisterStreamConsumerCommand, RemoveTagsFromStreamCommand, ResourceNotFoundException as ResourceNotFoundException$12, StartStreamEncryptionCommand, StopStreamEncryptionCommand, TagResourceCommand as TagResourceCommand$20, UntagResourceCommand as UntagResourceCommand$20, UpdateMaxRecordSizeCommand, UpdateShardCountCommand, UpdateStreamModeCommand } from "@aws-sdk/client-kinesis";
|
|
53
|
+
import { CreateScheduleCommand, DeleteScheduleCommand, GetScheduleCommand, ListSchedulesCommand, ResourceNotFoundException as ResourceNotFoundException$13, SchedulerClient, UpdateScheduleCommand } from "@aws-sdk/client-scheduler";
|
|
52
54
|
import { CreatePipeCommand, DeletePipeCommand, DescribePipeCommand, NotFoundException as NotFoundException$6, PipesClient, TagResourceCommand as TagResourceCommand$21, UntagResourceCommand as UntagResourceCommand$21, UpdatePipeCommand } from "@aws-sdk/client-pipes";
|
|
53
55
|
import { AccessPointAlreadyExists, AccessPointNotFound, CreateAccessPointCommand, CreateFileSystemCommand, CreateMountTargetCommand, DeleteAccessPointCommand, DeleteFileSystemCommand, DeleteMountTargetCommand, DescribeAccessPointsCommand, DescribeBackupPolicyCommand, DescribeFileSystemPolicyCommand, DescribeFileSystemsCommand, DescribeLifecycleConfigurationCommand, DescribeMountTargetSecurityGroupsCommand, DescribeMountTargetsCommand, EFSClient, FileSystemAlreadyExists, FileSystemNotFound, ModifyMountTargetSecurityGroupsCommand, MountTargetNotFound, PutBackupPolicyCommand, PutFileSystemPolicyCommand, PutLifecycleConfigurationCommand, UpdateFileSystemCommand, UpdateFileSystemProtectionCommand } from "@aws-sdk/client-efs";
|
|
54
56
|
import { CreateFileSystemCommand as CreateFileSystemCommand$1, CreateFileSystemFromBackupCommand, DeleteFileSystemCommand as DeleteFileSystemCommand$1, DescribeFileSystemsCommand as DescribeFileSystemsCommand$1, FSxClient, FileSystemNotFound as FileSystemNotFound$1, TagResourceCommand as TagResourceCommand$22, UntagResourceCommand as UntagResourceCommand$22, UpdateFileSystemCommand as UpdateFileSystemCommand$1 } from "@aws-sdk/client-fsx";
|
|
55
57
|
import { AddInstanceFleetCommand, AddInstanceGroupsCommand, AddTagsCommand as AddTagsCommand$1, DescribeClusterCommand, EMRClient, InvalidRequestException, ListClustersCommand, ListInstanceFleetsCommand, ListInstanceGroupsCommand, ModifyClusterCommand, ModifyInstanceFleetCommand, ModifyInstanceGroupsCommand, PutAutoScalingPolicyCommand, PutAutoTerminationPolicyCommand, PutManagedScalingPolicyCommand, RemoveAutoScalingPolicyCommand, RemoveAutoTerminationPolicyCommand, RemoveManagedScalingPolicyCommand, RemoveTagsCommand as RemoveTagsCommand$1, RunJobFlowCommand, SetTerminationProtectionCommand, SetVisibleToAllUsersCommand, TerminateJobFlowsCommand } from "@aws-sdk/client-emr";
|
|
56
|
-
import { CreateDeliveryStreamCommand, DeleteDeliveryStreamCommand, DescribeDeliveryStreamCommand, FirehoseClient, ListTagsForDeliveryStreamCommand, ResourceNotFoundException as ResourceNotFoundException$
|
|
58
|
+
import { CreateDeliveryStreamCommand, DeleteDeliveryStreamCommand, DescribeDeliveryStreamCommand, FirehoseClient, ListTagsForDeliveryStreamCommand, ResourceNotFoundException as ResourceNotFoundException$14, TagDeliveryStreamCommand, UntagDeliveryStreamCommand, UpdateDestinationCommand } from "@aws-sdk/client-firehose";
|
|
57
59
|
import { AddTagsCommand as AddTagsCommand$2, CloudTrailClient, CreateTrailCommand, DeleteTrailCommand, GetEventSelectorsCommand, GetInsightSelectorsCommand, GetTrailCommand, GetTrailStatusCommand, ListTagsCommand as ListTagsCommand$2, PutEventSelectorsCommand, PutInsightSelectorsCommand, RemoveTagsCommand as RemoveTagsCommand$2, StartLoggingCommand, StopLoggingCommand, TrailNotFoundException, UpdateTrailCommand } from "@aws-sdk/client-cloudtrail";
|
|
58
|
-
import { BatchGetProjectsCommand, CodeBuildClient, CreateProjectCommand, DeleteProjectCommand, ResourceNotFoundException as ResourceNotFoundException$
|
|
60
|
+
import { BatchGetProjectsCommand, CodeBuildClient, CreateProjectCommand, DeleteProjectCommand, ResourceNotFoundException as ResourceNotFoundException$15, UpdateProjectCommand } from "@aws-sdk/client-codebuild";
|
|
59
61
|
import { CodeCommitClient, CreateCommitCommand, CreateRepositoryCommand as CreateRepositoryCommand$1, DeleteRepositoryCommand as DeleteRepositoryCommand$1, GetRepositoryCommand, GetRepositoryTriggersCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$16, PutRepositoryTriggersCommand, RepositoryDoesNotExistException, TagResourceCommand as TagResourceCommand$23, UntagResourceCommand as UntagResourceCommand$23, UpdateRepositoryDescriptionCommand, UpdateRepositoryEncryptionKeyCommand, UpdateRepositoryNameCommand } from "@aws-sdk/client-codecommit";
|
|
60
|
-
import { CreateLifecyclePolicyCommand, DLMClient, DeleteLifecyclePolicyCommand as DeleteLifecyclePolicyCommand$1, GetLifecyclePoliciesCommand, GetLifecyclePolicyCommand as GetLifecyclePolicyCommand$1, ResourceNotFoundException as ResourceNotFoundException$
|
|
62
|
+
import { CreateLifecyclePolicyCommand, DLMClient, DeleteLifecyclePolicyCommand as DeleteLifecyclePolicyCommand$1, GetLifecyclePoliciesCommand, GetLifecyclePolicyCommand as GetLifecyclePolicyCommand$1, ResourceNotFoundException as ResourceNotFoundException$16, TagResourceCommand as TagResourceCommand$24, UntagResourceCommand as UntagResourceCommand$24, UpdateLifecyclePolicyCommand } from "@aws-sdk/client-dlm";
|
|
61
63
|
import { CreateVectorBucketCommand, DeleteIndexCommand, DeleteVectorBucketCommand, GetVectorBucketCommand, ListIndexesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$17, S3VectorsClient, TagResourceCommand as TagResourceCommand$25, UntagResourceCommand as UntagResourceCommand$25 } from "@aws-sdk/client-s3vectors";
|
|
62
64
|
import { ListTagsForResourceCommand as ListTagsForResourceCommand$18, S3ControlClient, TagResourceCommand as TagResourceCommand$26, UntagResourceCommand as UntagResourceCommand$26 } from "@aws-sdk/client-s3-control";
|
|
63
65
|
import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as CreateTableCommand$2, DeleteNamespaceCommand as DeleteNamespaceCommand$1, DeleteTableBucketCommand, DeleteTableCommand as DeleteTableCommand$2, GetNamespaceCommand as GetNamespaceCommand$1, GetTableBucketCommand, GetTableCommand as GetTableCommand$1, ListNamespacesCommand as ListNamespacesCommand$1, ListTableBucketsCommand, ListTablesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$19, NotFoundException as NotFoundException$7, S3TablesClient, TagResourceCommand as TagResourceCommand$27, UntagResourceCommand as UntagResourceCommand$27 } from "@aws-sdk/client-s3tables";
|
|
@@ -415,7 +417,9 @@ var IAMPolicyProvider = class {
|
|
|
415
417
|
}
|
|
416
418
|
let secretPrincipalLacksGrant = false;
|
|
417
419
|
const detached = context?.resolveSecretDerivedPrincipals?.retryMemo?.detached;
|
|
420
|
+
let removedAny = false;
|
|
418
421
|
const onDetached = (kind, name) => {
|
|
422
|
+
removedAny = true;
|
|
419
423
|
if (fromSecret(kind, name)) detached?.add(injectiveKey(kind, name));
|
|
420
424
|
};
|
|
421
425
|
const claimed = (kind, name) => {
|
|
@@ -503,7 +507,8 @@ var IAMPolicyProvider = class {
|
|
|
503
507
|
this.logger.debug(`Successfully deleted IAM policy ${logicalId}`);
|
|
504
508
|
} catch (error) {
|
|
505
509
|
const cause = error instanceof Error ? error : void 0;
|
|
506
|
-
|
|
510
|
+
const failure = new ProvisioningError(`Failed to delete IAM policy ${logicalId}: ${mask(error instanceof Error ? error.message : String(error))}`, resourceType, logicalId, physicalId, cause);
|
|
511
|
+
throw maskError(removedAny ? markDeleteStarted(failure) : failure);
|
|
507
512
|
}
|
|
508
513
|
}
|
|
509
514
|
async readCurrentState(physicalId, _logicalId, _resourceType, properties) {
|
|
@@ -770,6 +775,7 @@ var IAMManagedPolicyProvider = class {
|
|
|
770
775
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
771
776
|
const mask = maskerOrIdentity(context?.maskSecrets);
|
|
772
777
|
this.logger.debug(mask(`Deleting IAM managed policy ${logicalId}: ${physicalId}`));
|
|
778
|
+
const progress = { stripped: false };
|
|
773
779
|
try {
|
|
774
780
|
try {
|
|
775
781
|
await this.iamClient.send(new GetPolicyCommand({ PolicyArn: physicalId }));
|
|
@@ -780,7 +786,7 @@ var IAMManagedPolicyProvider = class {
|
|
|
780
786
|
}
|
|
781
787
|
throw error;
|
|
782
788
|
}
|
|
783
|
-
await this.detachAllPrincipals(physicalId);
|
|
789
|
+
await this.detachAllPrincipals(physicalId, progress);
|
|
784
790
|
await this.deleteAllNonDefaultVersions(physicalId);
|
|
785
791
|
await this.iamClient.send(new DeletePolicyCommand({ PolicyArn: physicalId }));
|
|
786
792
|
this.logger.debug(`Successfully deleted IAM managed policy ${logicalId}`);
|
|
@@ -790,7 +796,8 @@ var IAMManagedPolicyProvider = class {
|
|
|
790
796
|
return;
|
|
791
797
|
}
|
|
792
798
|
const cause = error instanceof Error ? error : void 0;
|
|
793
|
-
|
|
799
|
+
const failure = this.wrapMaskedError(mask, error, (text) => new ProvisioningError(`Failed to delete IAM managed policy ${logicalId}: ${text}`, resourceType, logicalId, physicalId, cause));
|
|
800
|
+
throw progress.stripped ? markDeleteStarted(failure) : failure;
|
|
794
801
|
}
|
|
795
802
|
}
|
|
796
803
|
async goneOnDelete(logicalId, physicalId, resourceType, context, mask) {
|
|
@@ -1033,7 +1040,7 @@ var IAMManagedPolicyProvider = class {
|
|
|
1033
1040
|
} while (marker);
|
|
1034
1041
|
return live;
|
|
1035
1042
|
}
|
|
1036
|
-
async detachAllPrincipals(policyArn) {
|
|
1043
|
+
async detachAllPrincipals(policyArn, progress) {
|
|
1037
1044
|
try {
|
|
1038
1045
|
let marker;
|
|
1039
1046
|
while (true) {
|
|
@@ -1048,6 +1055,7 @@ var IAMManagedPolicyProvider = class {
|
|
|
1048
1055
|
GroupName: g.GroupName,
|
|
1049
1056
|
PolicyArn: policyArn
|
|
1050
1057
|
}));
|
|
1058
|
+
if (progress) progress.stripped = true;
|
|
1051
1059
|
} catch (err) {
|
|
1052
1060
|
if (!(err instanceof NoSuchEntityException)) throw err;
|
|
1053
1061
|
}
|
|
@@ -1059,6 +1067,7 @@ var IAMManagedPolicyProvider = class {
|
|
|
1059
1067
|
RoleName: r.RoleName,
|
|
1060
1068
|
PolicyArn: policyArn
|
|
1061
1069
|
}));
|
|
1070
|
+
if (progress) progress.stripped = true;
|
|
1062
1071
|
} catch (err) {
|
|
1063
1072
|
if (!(err instanceof NoSuchEntityException)) throw err;
|
|
1064
1073
|
}
|
|
@@ -1070,6 +1079,7 @@ var IAMManagedPolicyProvider = class {
|
|
|
1070
1079
|
UserName: u.UserName,
|
|
1071
1080
|
PolicyArn: policyArn
|
|
1072
1081
|
}));
|
|
1082
|
+
if (progress) progress.stripped = true;
|
|
1073
1083
|
} catch (err) {
|
|
1074
1084
|
if (!(err instanceof NoSuchEntityException)) throw err;
|
|
1075
1085
|
}
|
|
@@ -1315,6 +1325,7 @@ var IAMInstanceProfileProvider = class {
|
|
|
1315
1325
|
}
|
|
1316
1326
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
1317
1327
|
this.logger.debug(`Deleting IAM instance profile ${logicalId}: ${physicalId}`);
|
|
1328
|
+
let stripped = false;
|
|
1318
1329
|
try {
|
|
1319
1330
|
let roles = [];
|
|
1320
1331
|
try {
|
|
@@ -1333,6 +1344,7 @@ var IAMInstanceProfileProvider = class {
|
|
|
1333
1344
|
InstanceProfileName: physicalId,
|
|
1334
1345
|
RoleName: roleName
|
|
1335
1346
|
}));
|
|
1347
|
+
stripped = true;
|
|
1336
1348
|
this.logger.debug(`Removed role ${roleName} from instance profile ${physicalId}`);
|
|
1337
1349
|
} catch (error) {
|
|
1338
1350
|
if (!(error instanceof NoSuchEntityException)) throw error;
|
|
@@ -1347,7 +1359,8 @@ var IAMInstanceProfileProvider = class {
|
|
|
1347
1359
|
return;
|
|
1348
1360
|
}
|
|
1349
1361
|
const cause = error instanceof Error ? error : void 0;
|
|
1350
|
-
|
|
1362
|
+
const failure = new ProvisioningError(`Failed to delete IAM instance profile ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
1363
|
+
throw stripped ? markDeleteStarted(failure) : failure;
|
|
1351
1364
|
}
|
|
1352
1365
|
}
|
|
1353
1366
|
logGoneOnDelete(logicalId, physicalId, context) {
|
|
@@ -1421,6 +1434,7 @@ var IAMInstanceProfileProvider = class {
|
|
|
1421
1434
|
|
|
1422
1435
|
//#endregion
|
|
1423
1436
|
//#region src/provisioning/providers/iam-access-key-provider.ts
|
|
1437
|
+
const ACCESS_KEY_ID_PATTERN = /^AKIA[A-Z0-9]{16}$/;
|
|
1424
1438
|
const CREATE_DATE_SKEW_MARGIN_MS = 5e3;
|
|
1425
1439
|
var IAMAccessKeyProvider = class {
|
|
1426
1440
|
iamClient;
|
|
@@ -1510,7 +1524,10 @@ var IAMAccessKeyProvider = class {
|
|
|
1510
1524
|
if (leftBehindKeyId !== void 0 && reconciled.has(leftBehindKeyId)) leftBehindKeyId = void 0;
|
|
1511
1525
|
const cause = error instanceof Error ? error : void 0;
|
|
1512
1526
|
const thrown = this.wrapMaskedError(log.mask, error, (text) => new ProvisioningError(`Failed to create IAM access key ${logicalId}: ${text}`, resourceType, logicalId, void 0, cause));
|
|
1513
|
-
if (leftBehindKeyId !== void 0)
|
|
1527
|
+
if (leftBehindKeyId !== void 0) {
|
|
1528
|
+
markCreatedBeforeFailure(thrown, logicalId, resourceType, leftBehindKeyId);
|
|
1529
|
+
markNonRetryable(thrown);
|
|
1530
|
+
}
|
|
1514
1531
|
throw thrown;
|
|
1515
1532
|
}
|
|
1516
1533
|
}
|
|
@@ -1640,9 +1657,16 @@ var IAMAccessKeyProvider = class {
|
|
|
1640
1657
|
throw new ProvisioningError(`Unknown attribute ${attributeName} for ${resourceType} (only 'Id' and 'SecretAccessKey' are defined)`, resourceType, logicalId, physicalId);
|
|
1641
1658
|
}
|
|
1642
1659
|
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
1660
|
+
const found = await this.findAccessKey(physicalId);
|
|
1661
|
+
if (found === void 0 || found === RESOURCE_NOT_FOUND) return found;
|
|
1662
|
+
const result = { UserName: found.userName };
|
|
1663
|
+
if (found.status !== void 0) result["Status"] = found.status;
|
|
1664
|
+
return result;
|
|
1665
|
+
}
|
|
1666
|
+
async findAccessKey(accessKeyId) {
|
|
1643
1667
|
let userName;
|
|
1644
1668
|
try {
|
|
1645
|
-
userName = (await this.iamClient.send(new GetAccessKeyLastUsedCommand({ AccessKeyId:
|
|
1669
|
+
userName = (await this.iamClient.send(new GetAccessKeyLastUsedCommand({ AccessKeyId: accessKeyId }))).UserName;
|
|
1646
1670
|
} catch (err) {
|
|
1647
1671
|
if (err instanceof NoSuchEntityException) return RESOURCE_NOT_FOUND;
|
|
1648
1672
|
throw err;
|
|
@@ -1660,15 +1684,23 @@ var IAMAccessKeyProvider = class {
|
|
|
1660
1684
|
if (err instanceof NoSuchEntityException) return RESOURCE_NOT_FOUND;
|
|
1661
1685
|
throw err;
|
|
1662
1686
|
}
|
|
1663
|
-
for (const key of page.AccessKeyMetadata ?? []) if (key.AccessKeyId ===
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
}
|
|
1687
|
+
for (const key of page.AccessKeyMetadata ?? []) if (key.AccessKeyId === accessKeyId) return {
|
|
1688
|
+
userName,
|
|
1689
|
+
status: key.Status
|
|
1690
|
+
};
|
|
1668
1691
|
marker = page.IsTruncated ? page.Marker : void 0;
|
|
1669
1692
|
} while (marker);
|
|
1670
1693
|
return RESOURCE_NOT_FOUND;
|
|
1671
1694
|
}
|
|
1695
|
+
async isSameResource(journaledPhysicalId, record, resourceType, context) {
|
|
1696
|
+
if (resourceType !== "AWS::IAM::AccessKey") return "unknown";
|
|
1697
|
+
if (!ACCESS_KEY_ID_PATTERN.test(journaledPhysicalId) || !ACCESS_KEY_ID_PATTERN.test(record.physicalId)) return "unknown";
|
|
1698
|
+
if (journaledPhysicalId === record.physicalId) return "same";
|
|
1699
|
+
if (await this.iamClient.config.region() !== context.expectedRegion) return "unknown";
|
|
1700
|
+
const recordKey = await this.findAccessKey(record.physicalId);
|
|
1701
|
+
if (recordKey === void 0 || recordKey === RESOURCE_NOT_FOUND) return "unknown";
|
|
1702
|
+
return await this.findAccessKey(journaledPhysicalId) === void 0 ? "unknown" : "different";
|
|
1703
|
+
}
|
|
1672
1704
|
getDriftUnknownPaths(resourceType) {
|
|
1673
1705
|
if (resourceType === "AWS::IAM::AccessKey") return ["Serial"];
|
|
1674
1706
|
return [];
|
|
@@ -1981,9 +2013,11 @@ var IAMUserGroupProvider = class {
|
|
|
1981
2013
|
const log = createMaskedLogSinks(this.logger, context?.maskSecrets);
|
|
1982
2014
|
const { value: v } = log;
|
|
1983
2015
|
log.debug(`Deleting IAM user ${logicalId}: ${v(physicalId)}`);
|
|
2016
|
+
const progress = { stripped: false };
|
|
2017
|
+
let hadBoundary = false;
|
|
1984
2018
|
try {
|
|
1985
2019
|
try {
|
|
1986
|
-
await this.iamClient.send(new GetUserCommand({ UserName: physicalId }));
|
|
2020
|
+
hadBoundary = (await this.iamClient.send(new GetUserCommand({ UserName: physicalId }))).User?.PermissionsBoundary !== void 0;
|
|
1987
2021
|
} catch (error) {
|
|
1988
2022
|
if (error instanceof NoSuchEntityException) {
|
|
1989
2023
|
const clientRegion = await this.iamClient.config.region();
|
|
@@ -1994,18 +2028,20 @@ var IAMUserGroupProvider = class {
|
|
|
1994
2028
|
}
|
|
1995
2029
|
throw error;
|
|
1996
2030
|
}
|
|
1997
|
-
await this.removeUserFromAllGroups(physicalId, log);
|
|
1998
|
-
await this.detachAllUserPolicies(physicalId, log);
|
|
1999
|
-
await this.deleteAllUserInlinePolicies(physicalId, log);
|
|
2031
|
+
await this.removeUserFromAllGroups(physicalId, log, progress);
|
|
2032
|
+
await this.detachAllUserPolicies(physicalId, log, progress);
|
|
2033
|
+
await this.deleteAllUserInlinePolicies(physicalId, log, progress);
|
|
2000
2034
|
try {
|
|
2001
2035
|
await this.iamClient.send(new DeleteLoginProfileCommand({ UserName: physicalId }));
|
|
2036
|
+
progress.stripped = true;
|
|
2002
2037
|
log.debug(`Deleted login profile for user ${v(physicalId)}`);
|
|
2003
2038
|
} catch (error) {
|
|
2004
2039
|
if (!(error instanceof NoSuchEntityException)) throw error;
|
|
2005
2040
|
}
|
|
2006
|
-
await this.deleteAllAccessKeys(physicalId, log);
|
|
2041
|
+
await this.deleteAllAccessKeys(physicalId, log, progress);
|
|
2007
2042
|
try {
|
|
2008
2043
|
await this.iamClient.send(new DeleteUserPermissionsBoundaryCommand({ UserName: physicalId }));
|
|
2044
|
+
if (hadBoundary) progress.stripped = true;
|
|
2009
2045
|
} catch (error) {
|
|
2010
2046
|
if (!(error instanceof NoSuchEntityException)) throw error;
|
|
2011
2047
|
}
|
|
@@ -2013,7 +2049,8 @@ var IAMUserGroupProvider = class {
|
|
|
2013
2049
|
log.debug(`Successfully deleted IAM user ${logicalId}`);
|
|
2014
2050
|
} catch (error) {
|
|
2015
2051
|
const cause = error instanceof Error ? error : void 0;
|
|
2016
|
-
|
|
2052
|
+
const failure = new ProvisioningError(log.mask(`Failed to delete IAM user ${logicalId}: ${error instanceof Error ? error.message : String(error)}`), resourceType, logicalId, physicalId, cause);
|
|
2053
|
+
throw progress.stripped ? markDeleteStarted(failure) : failure;
|
|
2017
2054
|
}
|
|
2018
2055
|
}
|
|
2019
2056
|
async readLiveGroups(userName) {
|
|
@@ -2029,7 +2066,7 @@ var IAMUserGroupProvider = class {
|
|
|
2029
2066
|
} while (marker);
|
|
2030
2067
|
return groups;
|
|
2031
2068
|
}
|
|
2032
|
-
async removeUserFromAllGroups(userName, log) {
|
|
2069
|
+
async removeUserFromAllGroups(userName, log, progress) {
|
|
2033
2070
|
const { value: v } = log;
|
|
2034
2071
|
try {
|
|
2035
2072
|
const groups = (await this.iamClient.send(new ListGroupsForUserCommand({ UserName: userName }))).Groups || [];
|
|
@@ -2038,6 +2075,7 @@ var IAMUserGroupProvider = class {
|
|
|
2038
2075
|
UserName: userName,
|
|
2039
2076
|
GroupName: group.GroupName
|
|
2040
2077
|
}));
|
|
2078
|
+
if (progress) progress.stripped = true;
|
|
2041
2079
|
log.debug(`Removed user ${v(userName)} from group ${v(group.GroupName)}`);
|
|
2042
2080
|
} catch (error) {
|
|
2043
2081
|
if (!(error instanceof NoSuchEntityException)) throw error;
|
|
@@ -2047,7 +2085,7 @@ var IAMUserGroupProvider = class {
|
|
|
2047
2085
|
throw error;
|
|
2048
2086
|
}
|
|
2049
2087
|
}
|
|
2050
|
-
async deleteAllAccessKeys(userName, log) {
|
|
2088
|
+
async deleteAllAccessKeys(userName, log, progress) {
|
|
2051
2089
|
const { value: v } = log;
|
|
2052
2090
|
try {
|
|
2053
2091
|
const keys = (await this.iamClient.send(new ListAccessKeysCommand({ UserName: userName }))).AccessKeyMetadata || [];
|
|
@@ -2056,6 +2094,7 @@ var IAMUserGroupProvider = class {
|
|
|
2056
2094
|
UserName: userName,
|
|
2057
2095
|
AccessKeyId: key.AccessKeyId
|
|
2058
2096
|
}));
|
|
2097
|
+
if (progress) progress.stripped = true;
|
|
2059
2098
|
log.debug(`Deleted access key ${key.AccessKeyId} for user ${v(userName)}`);
|
|
2060
2099
|
}
|
|
2061
2100
|
} catch (error) {
|
|
@@ -2063,7 +2102,7 @@ var IAMUserGroupProvider = class {
|
|
|
2063
2102
|
throw error;
|
|
2064
2103
|
}
|
|
2065
2104
|
}
|
|
2066
|
-
async detachAllUserPolicies(userName, log) {
|
|
2105
|
+
async detachAllUserPolicies(userName, log, progress) {
|
|
2067
2106
|
const { value: v } = log;
|
|
2068
2107
|
try {
|
|
2069
2108
|
const policies = (await this.iamClient.send(new ListAttachedUserPoliciesCommand({ UserName: userName }))).AttachedPolicies || [];
|
|
@@ -2072,6 +2111,7 @@ var IAMUserGroupProvider = class {
|
|
|
2072
2111
|
UserName: userName,
|
|
2073
2112
|
PolicyArn: policy.PolicyArn
|
|
2074
2113
|
}));
|
|
2114
|
+
if (progress) progress.stripped = true;
|
|
2075
2115
|
log.debug(`Detached managed policy ${v(policy.PolicyArn)} from user ${v(userName)}`);
|
|
2076
2116
|
} catch (error) {
|
|
2077
2117
|
if (!(error instanceof NoSuchEntityException)) throw error;
|
|
@@ -2081,7 +2121,7 @@ var IAMUserGroupProvider = class {
|
|
|
2081
2121
|
throw error;
|
|
2082
2122
|
}
|
|
2083
2123
|
}
|
|
2084
|
-
async deleteAllUserInlinePolicies(userName, log) {
|
|
2124
|
+
async deleteAllUserInlinePolicies(userName, log, progress) {
|
|
2085
2125
|
const { value: v } = log;
|
|
2086
2126
|
try {
|
|
2087
2127
|
const policyNames = (await this.iamClient.send(new ListUserPoliciesCommand({ UserName: userName }))).PolicyNames || [];
|
|
@@ -2090,6 +2130,7 @@ var IAMUserGroupProvider = class {
|
|
|
2090
2130
|
UserName: userName,
|
|
2091
2131
|
PolicyName: policyName
|
|
2092
2132
|
}));
|
|
2133
|
+
if (progress) progress.stripped = true;
|
|
2093
2134
|
log.debug(`Deleted inline policy ${v(policyName)} from user ${v(userName)}`);
|
|
2094
2135
|
} catch (error) {
|
|
2095
2136
|
if (!(error instanceof NoSuchEntityException)) throw error;
|
|
@@ -2273,10 +2314,11 @@ var IAMUserGroupProvider = class {
|
|
|
2273
2314
|
const log = createMaskedLogSinks(this.logger, context?.maskSecrets);
|
|
2274
2315
|
const { value: v } = log;
|
|
2275
2316
|
log.debug(`Deleting IAM group ${logicalId}: ${v(physicalId)}`);
|
|
2317
|
+
const progress = { stripped: false };
|
|
2276
2318
|
try {
|
|
2277
|
-
await this.detachAllGroupPolicies(physicalId, log);
|
|
2278
|
-
await this.deleteAllGroupInlinePolicies(physicalId, log);
|
|
2279
|
-
await this.removeAllUsersFromGroup(physicalId, log);
|
|
2319
|
+
await this.detachAllGroupPolicies(physicalId, log, progress);
|
|
2320
|
+
await this.deleteAllGroupInlinePolicies(physicalId, log, progress);
|
|
2321
|
+
await this.removeAllUsersFromGroup(physicalId, log, progress);
|
|
2280
2322
|
await this.iamClient.send(new DeleteGroupCommand({ GroupName: physicalId }));
|
|
2281
2323
|
log.debug(`Successfully deleted IAM group ${logicalId}`);
|
|
2282
2324
|
} catch (error) {
|
|
@@ -2288,10 +2330,11 @@ var IAMUserGroupProvider = class {
|
|
|
2288
2330
|
return;
|
|
2289
2331
|
}
|
|
2290
2332
|
const cause = error instanceof Error ? error : void 0;
|
|
2291
|
-
|
|
2333
|
+
const failure = new ProvisioningError(log.mask(`Failed to delete IAM group ${logicalId}: ${error instanceof Error ? error.message : String(error)}`), resourceType, logicalId, physicalId, cause);
|
|
2334
|
+
throw progress.stripped ? markDeleteStarted(failure) : failure;
|
|
2292
2335
|
}
|
|
2293
2336
|
}
|
|
2294
|
-
async detachAllGroupPolicies(groupName, log) {
|
|
2337
|
+
async detachAllGroupPolicies(groupName, log, progress) {
|
|
2295
2338
|
const { value: v } = log;
|
|
2296
2339
|
try {
|
|
2297
2340
|
const policies = (await this.iamClient.send(new ListAttachedGroupPoliciesCommand({ GroupName: groupName }))).AttachedPolicies || [];
|
|
@@ -2300,6 +2343,7 @@ var IAMUserGroupProvider = class {
|
|
|
2300
2343
|
GroupName: groupName,
|
|
2301
2344
|
PolicyArn: policy.PolicyArn
|
|
2302
2345
|
}));
|
|
2346
|
+
if (progress) progress.stripped = true;
|
|
2303
2347
|
log.debug(`Detached managed policy ${v(policy.PolicyArn)} from group ${v(groupName)}`);
|
|
2304
2348
|
} catch (error) {
|
|
2305
2349
|
if (!(error instanceof NoSuchEntityException)) throw error;
|
|
@@ -2309,7 +2353,7 @@ var IAMUserGroupProvider = class {
|
|
|
2309
2353
|
throw error;
|
|
2310
2354
|
}
|
|
2311
2355
|
}
|
|
2312
|
-
async removeAllUsersFromGroup(groupName, log) {
|
|
2356
|
+
async removeAllUsersFromGroup(groupName, log, progress) {
|
|
2313
2357
|
const { value: v } = log;
|
|
2314
2358
|
try {
|
|
2315
2359
|
const users = (await this.iamClient.send(new GetGroupCommand({ GroupName: groupName }))).Users || [];
|
|
@@ -2318,6 +2362,7 @@ var IAMUserGroupProvider = class {
|
|
|
2318
2362
|
GroupName: groupName,
|
|
2319
2363
|
UserName: user.UserName
|
|
2320
2364
|
}));
|
|
2365
|
+
if (progress) progress.stripped = true;
|
|
2321
2366
|
log.debug(`Removed user ${v(user.UserName)} from group ${v(groupName)}`);
|
|
2322
2367
|
} catch (error) {
|
|
2323
2368
|
if (!(error instanceof NoSuchEntityException)) throw error;
|
|
@@ -2346,7 +2391,7 @@ var IAMUserGroupProvider = class {
|
|
|
2346
2391
|
log.debug(`Detached managed policy ${v(policyArn)} from group ${v(groupName)}`);
|
|
2347
2392
|
}
|
|
2348
2393
|
}
|
|
2349
|
-
async deleteAllGroupInlinePolicies(groupName, log) {
|
|
2394
|
+
async deleteAllGroupInlinePolicies(groupName, log, progress) {
|
|
2350
2395
|
const { value: v } = log;
|
|
2351
2396
|
try {
|
|
2352
2397
|
const policyNames = (await this.iamClient.send(new ListGroupPoliciesCommand({ GroupName: groupName }))).PolicyNames || [];
|
|
@@ -2355,6 +2400,7 @@ var IAMUserGroupProvider = class {
|
|
|
2355
2400
|
GroupName: groupName,
|
|
2356
2401
|
PolicyName: policyName
|
|
2357
2402
|
}));
|
|
2403
|
+
if (progress) progress.stripped = true;
|
|
2358
2404
|
log.debug(`Deleted inline policy ${v(policyName)} from group ${v(groupName)}`);
|
|
2359
2405
|
} catch (error) {
|
|
2360
2406
|
if (!(error instanceof NoSuchEntityException)) throw error;
|
|
@@ -2528,6 +2574,7 @@ var IAMUserGroupProvider = class {
|
|
|
2528
2574
|
};
|
|
2529
2575
|
}
|
|
2530
2576
|
let secretUserNotMember = false;
|
|
2577
|
+
let removedAny = false;
|
|
2531
2578
|
try {
|
|
2532
2579
|
for (const userName of users ?? []) {
|
|
2533
2580
|
if (resolvedNames.has(userName) && memo?.detached.has(injectiveKey("Users", userName)) !== true) {
|
|
@@ -2549,6 +2596,7 @@ var IAMUserGroupProvider = class {
|
|
|
2549
2596
|
GroupName: groupName,
|
|
2550
2597
|
UserName: userName
|
|
2551
2598
|
}));
|
|
2599
|
+
removedAny = true;
|
|
2552
2600
|
if (resolvedNames.has(userName)) memo?.detached.add(injectiveKey("Users", userName));
|
|
2553
2601
|
this.logger.debug(`Removed user ${mask(userName)} from group ${groupName}`);
|
|
2554
2602
|
} catch (error) {
|
|
@@ -2566,7 +2614,8 @@ var IAMUserGroupProvider = class {
|
|
|
2566
2614
|
this.logger.debug(`Successfully deleted IAM UserToGroupAddition ${logicalId}`);
|
|
2567
2615
|
} catch (error) {
|
|
2568
2616
|
const cause = error instanceof Error ? error : void 0;
|
|
2569
|
-
|
|
2617
|
+
const failure = new ProvisioningError(`Failed to delete IAM UserToGroupAddition ${logicalId}: ${mask(error instanceof Error ? error.message : String(error))}`, resourceType, logicalId, physicalId, cause);
|
|
2618
|
+
throw maskError(removedAny ? markDeleteStarted(failure) : failure);
|
|
2570
2619
|
}
|
|
2571
2620
|
}
|
|
2572
2621
|
async isSameResource(journaledPhysicalId, record, resourceType, context) {
|
|
@@ -5419,7 +5468,7 @@ var S3BucketPolicyProvider = class {
|
|
|
5419
5468
|
const awsClients = getAwsClients();
|
|
5420
5469
|
this.s3Client = awsClients.s3;
|
|
5421
5470
|
}
|
|
5422
|
-
async create(logicalId, resourceType, properties) {
|
|
5471
|
+
async create(logicalId, resourceType, properties, context) {
|
|
5423
5472
|
this.logger.debug(`Creating S3 bucket policy ${logicalId}`);
|
|
5424
5473
|
const bucketName = properties["Bucket"];
|
|
5425
5474
|
const policyDocument = properties["PolicyDocument"];
|
|
@@ -5437,8 +5486,7 @@ var S3BucketPolicyProvider = class {
|
|
|
5437
5486
|
attributes: {}
|
|
5438
5487
|
};
|
|
5439
5488
|
} catch (error) {
|
|
5440
|
-
|
|
5441
|
-
throw new ProvisioningError(`Failed to create S3 bucket policy ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, bucketName, cause);
|
|
5489
|
+
throw this.wrapOperationError("create", logicalId, resourceType, bucketName, error, context?.maskSecrets);
|
|
5442
5490
|
}
|
|
5443
5491
|
}
|
|
5444
5492
|
async update(logicalId, physicalId, resourceType, properties, _previousProperties, context) {
|
|
@@ -5461,8 +5509,7 @@ var S3BucketPolicyProvider = class {
|
|
|
5461
5509
|
attributes: {}
|
|
5462
5510
|
};
|
|
5463
5511
|
} catch (error) {
|
|
5464
|
-
|
|
5465
|
-
throw new ProvisioningError(`Failed to update S3 bucket policy ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
5512
|
+
throw this.wrapOperationError("update", logicalId, resourceType, physicalId, error, context?.maskSecrets);
|
|
5466
5513
|
}
|
|
5467
5514
|
}
|
|
5468
5515
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
@@ -5487,10 +5534,17 @@ var S3BucketPolicyProvider = class {
|
|
|
5487
5534
|
throw error;
|
|
5488
5535
|
}
|
|
5489
5536
|
} catch (error) {
|
|
5490
|
-
|
|
5491
|
-
throw new ProvisioningError(`Failed to delete S3 bucket policy ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
5537
|
+
throw this.wrapOperationError("delete", logicalId, resourceType, physicalId, error, context?.maskSecrets);
|
|
5492
5538
|
}
|
|
5493
5539
|
}
|
|
5540
|
+
wrapOperationError(operation, logicalId, resourceType, physicalId, error, maskSecrets) {
|
|
5541
|
+
const mask = maskSecrets ?? ((t) => t);
|
|
5542
|
+
const failure = describeAwsFailure(error);
|
|
5543
|
+
if (failure.redacted) this.logger.debug(mask(`Failed to ${operation} S3 bucket policy ${logicalId}: ${failure.detail}`));
|
|
5544
|
+
const cause = error instanceof Error ? error : void 0;
|
|
5545
|
+
const wrapped = new ProvisioningError(`Failed to ${operation} S3 bucket policy ${logicalId}: ${failure.summary}`, resourceType, logicalId, physicalId, cause);
|
|
5546
|
+
return failure.redacted && cause !== void 0 ? markRedactedCause(wrapped) : wrapped;
|
|
5547
|
+
}
|
|
5494
5548
|
async readCurrentState(physicalId, _logicalId, _resourceType, properties, context) {
|
|
5495
5549
|
let policyJson;
|
|
5496
5550
|
try {
|
|
@@ -6049,7 +6103,7 @@ var SQSQueuePolicyProvider = class {
|
|
|
6049
6103
|
const awsClients = getAwsClients();
|
|
6050
6104
|
this.sqsClient = awsClients.sqs;
|
|
6051
6105
|
}
|
|
6052
|
-
async create(logicalId, resourceType, properties) {
|
|
6106
|
+
async create(logicalId, resourceType, properties, context) {
|
|
6053
6107
|
this.logger.debug(`Creating SQS queue policy ${logicalId}`);
|
|
6054
6108
|
const queues = properties["Queues"];
|
|
6055
6109
|
const policyDocument = properties["PolicyDocument"];
|
|
@@ -6072,8 +6126,7 @@ var SQSQueuePolicyProvider = class {
|
|
|
6072
6126
|
attributes: { [WRITTEN_QUEUES_KEY]: queues.join(",") }
|
|
6073
6127
|
};
|
|
6074
6128
|
} catch (error) {
|
|
6075
|
-
const
|
|
6076
|
-
const thrown = new ProvisioningError(`Failed to create SQS queue policy ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, queues[0], cause);
|
|
6129
|
+
const thrown = this.wrapOperationError("create", logicalId, resourceType, queues[0], error, context?.maskSecrets);
|
|
6077
6130
|
if (applied.length > 0) markCreatedBeforeFailure(thrown, logicalId, resourceType, applied.join(","));
|
|
6078
6131
|
throw thrown;
|
|
6079
6132
|
}
|
|
@@ -6105,8 +6158,7 @@ var SQSQueuePolicyProvider = class {
|
|
|
6105
6158
|
};
|
|
6106
6159
|
} catch (error) {
|
|
6107
6160
|
if (error instanceof ProvisioningError) throw error;
|
|
6108
|
-
|
|
6109
|
-
throw new ProvisioningError(`Failed to update SQS queue policy ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
6161
|
+
throw this.wrapOperationError("update", logicalId, resourceType, physicalId, error, context?.maskSecrets);
|
|
6110
6162
|
}
|
|
6111
6163
|
}
|
|
6112
6164
|
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
@@ -6115,12 +6167,13 @@ var SQSQueuePolicyProvider = class {
|
|
|
6115
6167
|
const named = physicalId.includes(",") ? splitQueueUrls(physicalId) : recordedQueues(physicalId, context?.recordedAttributes);
|
|
6116
6168
|
const queueUrls = [...physicalId.includes(",") ? [] : await this.queuesCarryingDocument(listedQueues(properties ?? {}).filter((url) => !named.includes(url)), properties?.["PolicyDocument"], logicalId), ...named];
|
|
6117
6169
|
if (queueUrls.length === 0) throw new ProvisioningError(`Failed to delete SQS queue policy ${logicalId}: its physical id names no queue URL`, resourceType, logicalId, physicalId);
|
|
6170
|
+
let clearedAny = false;
|
|
6118
6171
|
for (const queueUrl of queueUrls) try {
|
|
6119
6172
|
await this.clearQueuePolicy(queueUrl, resourceType, logicalId, context?.expectedRegion);
|
|
6173
|
+
clearedAny = true;
|
|
6120
6174
|
} catch (error) {
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
throw new ProvisioningError(`Failed to delete SQS queue policy ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
6175
|
+
const failure = error instanceof ProvisioningError ? error : this.wrapOperationError("delete", logicalId, resourceType, physicalId, error, context?.maskSecrets);
|
|
6176
|
+
throw clearedAny ? markDeleteStarted(failure) : failure;
|
|
6124
6177
|
}
|
|
6125
6178
|
this.logger.debug(`Successfully deleted SQS queue policy ${logicalId}`);
|
|
6126
6179
|
}
|
|
@@ -6165,7 +6218,7 @@ var SQSQueuePolicyProvider = class {
|
|
|
6165
6218
|
await this.clearQueuePolicy(queueUrl, resourceType, logicalId, context.expectedRegion);
|
|
6166
6219
|
} catch (error) {
|
|
6167
6220
|
if (error instanceof ProvisioningError) throw error;
|
|
6168
|
-
throw
|
|
6221
|
+
throw this.wrapOperationError("delete", logicalId, resourceType, physicalId, error, context.maskSecrets);
|
|
6169
6222
|
}
|
|
6170
6223
|
else {
|
|
6171
6224
|
mismatched = true;
|
|
@@ -6181,6 +6234,14 @@ var SQSQueuePolicyProvider = class {
|
|
|
6181
6234
|
leftInPlace: QUEUE_POLICY_MISMATCH_LEFT_REASON
|
|
6182
6235
|
};
|
|
6183
6236
|
}
|
|
6237
|
+
wrapOperationError(operation, logicalId, resourceType, physicalId, error, maskSecrets) {
|
|
6238
|
+
const mask = maskSecrets ?? ((t) => t);
|
|
6239
|
+
const failure = describeAwsFailure(error);
|
|
6240
|
+
if (failure.redacted) this.logger.debug(mask(`Failed to ${operation} SQS queue policy ${logicalId}: ${failure.detail}`));
|
|
6241
|
+
const cause = error instanceof Error ? error : void 0;
|
|
6242
|
+
const wrapped = new ProvisioningError(`Failed to ${operation} SQS queue policy ${logicalId}: ${failure.summary}`, resourceType, logicalId, physicalId, cause);
|
|
6243
|
+
return failure.redacted && cause !== void 0 ? markRedactedCause(wrapped) : wrapped;
|
|
6244
|
+
}
|
|
6184
6245
|
async clearQueuePolicy(queueUrl, resourceType, logicalId, expectedRegion, phase = "not-found") {
|
|
6185
6246
|
try {
|
|
6186
6247
|
await this.sqsClient.send(new SetQueueAttributesCommand({
|
|
@@ -7160,7 +7221,7 @@ const TOPIC_POLICY_NOT_COMPARED_LEFT_REASON = "the document it attempted is miss
|
|
|
7160
7221
|
var SNSTopicPolicyProvider = class {
|
|
7161
7222
|
logger = getLogger().child("SNSTopicPolicyProvider");
|
|
7162
7223
|
handledProperties = /* @__PURE__ */ new Map([["AWS::SNS::TopicPolicy", /* @__PURE__ */ new Set(["Topics", "PolicyDocument"])]]);
|
|
7163
|
-
async create(logicalId, resourceType, properties) {
|
|
7224
|
+
async create(logicalId, resourceType, properties, context) {
|
|
7164
7225
|
this.logger.debug(`Creating SNS topic policy ${logicalId}`);
|
|
7165
7226
|
const topics = properties["Topics"];
|
|
7166
7227
|
const policyDocument = properties["PolicyDocument"];
|
|
@@ -7179,7 +7240,7 @@ var SNSTopicPolicyProvider = class {
|
|
|
7179
7240
|
attributes: {}
|
|
7180
7241
|
};
|
|
7181
7242
|
} catch (error) {
|
|
7182
|
-
const thrown =
|
|
7243
|
+
const thrown = this.wrapOperationError("create", logicalId, resourceType, void 0, error, context?.maskSecrets);
|
|
7183
7244
|
if (applied.length > 0) markCreatedBeforeFailure(thrown, logicalId, resourceType, applied.join(","));
|
|
7184
7245
|
throw thrown;
|
|
7185
7246
|
}
|
|
@@ -7213,8 +7274,7 @@ var SNSTopicPolicyProvider = class {
|
|
|
7213
7274
|
};
|
|
7214
7275
|
} catch (error) {
|
|
7215
7276
|
if (error instanceof ProvisioningError) throw error;
|
|
7216
|
-
|
|
7217
|
-
throw new ProvisioningError(`Failed to update SNS topic policy ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
7277
|
+
throw this.wrapOperationError("update", logicalId, resourceType, physicalId, error, mask);
|
|
7218
7278
|
}
|
|
7219
7279
|
}
|
|
7220
7280
|
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
@@ -7224,12 +7284,13 @@ var SNSTopicPolicyProvider = class {
|
|
|
7224
7284
|
if (named.length === 0) throw markNonRetryable(new ProvisioningError(`Failed to delete SNS topic policy ${logicalId}: its physical id is empty, so cdkd changed no topic. Set each topic the policy is attached to back to its default policy by hand, then drop the record with ${stateOrphanRecordRemedy(context, logicalId)}.`, resourceType, logicalId, physicalId));
|
|
7225
7285
|
const topicArns = named.every((arn) => isSnsTopicArn(arn)) ? named : [.../* @__PURE__ */ new Set([...named.filter((arn) => isSnsTopicArn(arn)), ...listedTopics(properties ?? {})])];
|
|
7226
7286
|
if (topicArns.length === 0) throw markNonRetryable(new ProvisioningError(`Failed to delete SNS topic policy ${logicalId}: its physical id names no SNS topic ARN and its Topics lists none either, so cdkd changed no topic. Set each topic the policy is attached to back to its default policy by hand, then drop the record with ${stateOrphanRecordRemedy(context, logicalId)}.`, resourceType, logicalId, physicalId));
|
|
7287
|
+
let clearedAny = false;
|
|
7227
7288
|
for (const topicArn of topicArns) try {
|
|
7228
7289
|
await this.resetTopicPolicy(topicArn, resourceType, logicalId, context?.expectedRegion);
|
|
7290
|
+
clearedAny = true;
|
|
7229
7291
|
} catch (error) {
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
throw new ProvisioningError(`Failed to delete SNS topic policy ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
7292
|
+
const failure = error instanceof ProvisioningError ? error : this.wrapOperationError("delete", logicalId, resourceType, physicalId, error, context?.maskSecrets);
|
|
7293
|
+
throw clearedAny ? markDeleteStarted(failure) : failure;
|
|
7233
7294
|
}
|
|
7234
7295
|
this.logger.debug(`Successfully deleted SNS topic policy ${logicalId}`);
|
|
7235
7296
|
}
|
|
@@ -7281,7 +7342,7 @@ var SNSTopicPolicyProvider = class {
|
|
|
7281
7342
|
await this.resetTopicPolicy(topicArn, resourceType, logicalId, context.expectedRegion);
|
|
7282
7343
|
} catch (error) {
|
|
7283
7344
|
if (error instanceof ProvisioningError) throw error;
|
|
7284
|
-
throw
|
|
7345
|
+
throw this.wrapOperationError("delete", logicalId, resourceType, physicalId, error, context.maskSecrets);
|
|
7285
7346
|
}
|
|
7286
7347
|
continue;
|
|
7287
7348
|
}
|
|
@@ -7302,6 +7363,14 @@ var SNSTopicPolicyProvider = class {
|
|
|
7302
7363
|
leftInPlace: TOPIC_POLICY_MISMATCH_LEFT_REASON
|
|
7303
7364
|
};
|
|
7304
7365
|
}
|
|
7366
|
+
wrapOperationError(operation, logicalId, resourceType, physicalId, error, maskSecrets) {
|
|
7367
|
+
const mask = maskSecrets ?? ((t) => t);
|
|
7368
|
+
const failure = describeAwsFailure(error);
|
|
7369
|
+
if (failure.redacted) this.logger.debug(mask(`Failed to ${operation} SNS topic policy ${logicalId}: ${failure.detail}`));
|
|
7370
|
+
const cause = error instanceof Error ? error : void 0;
|
|
7371
|
+
const wrapped = new ProvisioningError(`Failed to ${operation} SNS topic policy ${logicalId}: ${failure.summary}`, resourceType, logicalId, physicalId, cause);
|
|
7372
|
+
return failure.redacted && cause !== void 0 ? markRedactedCause(wrapped) : wrapped;
|
|
7373
|
+
}
|
|
7305
7374
|
async resetTopicPolicy(topicArn, resourceType, logicalId, expectedRegion, phase = "not-found", mask = (t) => t) {
|
|
7306
7375
|
const defaultPolicy = defaultTopicPolicy(topicArn);
|
|
7307
7376
|
if (defaultPolicy === void 0) throw new ProvisioningError(`Cannot remove SNS topic policy ${logicalId} from ${topicArn}: not an SNS topic ARN`, resourceType, logicalId, topicArn);
|
|
@@ -8004,8 +8073,10 @@ var LambdaFunctionProvider = class {
|
|
|
8004
8073
|
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
8005
8074
|
this.logger.debug(`Deleting Lambda function ${logicalId}: ${physicalId}`);
|
|
8006
8075
|
const hasVpcConfig = this.hasVpcConfig(properties?.["VpcConfig"]);
|
|
8076
|
+
let stripped = false;
|
|
8007
8077
|
if (hasVpcConfig) {
|
|
8008
8078
|
try {
|
|
8079
|
+
stripped = true;
|
|
8009
8080
|
await this.lambdaClient.send(new UpdateFunctionConfigurationCommand({
|
|
8010
8081
|
FunctionName: physicalId,
|
|
8011
8082
|
VpcConfig: {
|
|
@@ -8021,6 +8092,7 @@ var LambdaFunctionProvider = class {
|
|
|
8021
8092
|
this.logFunctionGone(logicalId, physicalId, context);
|
|
8022
8093
|
return;
|
|
8023
8094
|
}
|
|
8095
|
+
if (isRefusedByName(error)) stripped = false;
|
|
8024
8096
|
this.logger.warn(`Pre-delete VPC detach failed for ${physicalId}: ${describeAwsFailure(error).detail} — continuing with delete`);
|
|
8025
8097
|
}
|
|
8026
8098
|
await this.waitForLambdaUpdateCompleted(physicalId);
|
|
@@ -8036,7 +8108,8 @@ var LambdaFunctionProvider = class {
|
|
|
8036
8108
|
return;
|
|
8037
8109
|
}
|
|
8038
8110
|
const cause = error instanceof Error ? error : void 0;
|
|
8039
|
-
|
|
8111
|
+
const failure = new ProvisioningError(`Failed to delete Lambda function ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
8112
|
+
throw stripped ? markDeleteStarted(failure) : failure;
|
|
8040
8113
|
}
|
|
8041
8114
|
if (hasVpcConfig) await this.cleanupLambdaEnis(physicalId);
|
|
8042
8115
|
}
|
|
@@ -10016,7 +10089,7 @@ var LambdaMicrovmImageProvider = class {
|
|
|
10016
10089
|
}
|
|
10017
10090
|
if (state === "CREATE_FAILED" || state === "UPDATE_FAILED") throw new Error(`MicroVM image ${logicalId} (${imageArn}) entered ${state} during ${operation}. Check the build logs in CloudWatch under /aws/lambda/microvms/ to diagnose.`);
|
|
10018
10091
|
this.logger.debug(`MicroVM image ${imageArn} state: ${state} (attempt ${attempt}/${this.maxPollAttempts})`);
|
|
10019
|
-
await sleep$
|
|
10092
|
+
await sleep$2(this.pollIntervalMs);
|
|
10020
10093
|
}
|
|
10021
10094
|
throw new Error(`MicroVM image ${logicalIdShown(logicalId)} ${isPlainImportValue(imageArn) ? `(${imageArn})` : VALUE_NOT_SHOWN} did not finish ${operation} within ${this.maxPollAttempts * this.pollIntervalMs / 1e3}s. Increase --resource-timeout AWS::Lambda::MicrovmImage=${commandHole("duration")} or set CDKD_NO_WAIT=true.`);
|
|
10022
10095
|
}
|
|
@@ -10031,7 +10104,7 @@ var LambdaMicrovmImageProvider = class {
|
|
|
10031
10104
|
}
|
|
10032
10105
|
if (resp.state === "DELETE_FAILED") throw new Error(`MicroVM image ${logicalId} (${imageArn}) entered DELETE_FAILED. Check the CloudWatch build logs under /aws/lambda/microvms/ to diagnose.`);
|
|
10033
10106
|
this.logger.debug(`MicroVM image ${imageArn} state: ${resp.state} (delete attempt ${attempt}/${this.maxPollAttempts})`);
|
|
10034
|
-
await sleep$
|
|
10107
|
+
await sleep$2(this.pollIntervalMs);
|
|
10035
10108
|
}
|
|
10036
10109
|
throw new Error(`MicroVM image ${logicalId} (${imageArn}) was not fully deleted within ${this.maxPollAttempts * this.pollIntervalMs / 1e3}s.`);
|
|
10037
10110
|
}
|
|
@@ -10075,7 +10148,7 @@ function positiveIntFromEnv(value, dflt) {
|
|
|
10075
10148
|
const n = Number(value);
|
|
10076
10149
|
return Number.isFinite(n) && n > 0 ? n : dflt;
|
|
10077
10150
|
}
|
|
10078
|
-
function sleep$
|
|
10151
|
+
function sleep$2(ms) {
|
|
10079
10152
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
10080
10153
|
}
|
|
10081
10154
|
function buildCommonImageInput(properties) {
|
|
@@ -10143,6 +10216,957 @@ function isRecord$1(value) {
|
|
|
10143
10216
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10144
10217
|
}
|
|
10145
10218
|
|
|
10219
|
+
//#endregion
|
|
10220
|
+
//#region src/provisioning/providers/lambda-web-function-arns.ts
|
|
10221
|
+
const CHILD_ARN = /^(arn:[^:]+:lambda:[^:]+:\d{12}:web-function\/[^/]+)\/(revision|endpoint)\/([^/]+)$/;
|
|
10222
|
+
function parseWebFunctionChildArn(arn, kind) {
|
|
10223
|
+
const match = CHILD_ARN.exec(arn);
|
|
10224
|
+
if (!match || match[2] !== kind) return void 0;
|
|
10225
|
+
return {
|
|
10226
|
+
functionArn: match[1],
|
|
10227
|
+
childId: match[3]
|
|
10228
|
+
};
|
|
10229
|
+
}
|
|
10230
|
+
function webFunctionNameOfArn(functionArn) {
|
|
10231
|
+
return functionArn.slice(functionArn.lastIndexOf("/") + 1);
|
|
10232
|
+
}
|
|
10233
|
+
function recordedFunctionNameSpelling(recorded, liveFunctionArn) {
|
|
10234
|
+
if (typeof recorded === "string" && (recorded === liveFunctionArn || recorded === webFunctionNameOfArn(liveFunctionArn))) return recorded;
|
|
10235
|
+
return liveFunctionArn;
|
|
10236
|
+
}
|
|
10237
|
+
function projectOntoRecorded(recorded, live) {
|
|
10238
|
+
if (!isPlainRecord$2(recorded) || !isPlainRecord$2(live)) return live;
|
|
10239
|
+
const out = {};
|
|
10240
|
+
for (const key of Object.keys(recorded)) {
|
|
10241
|
+
if (!Object.prototype.hasOwnProperty.call(live, key)) continue;
|
|
10242
|
+
out[key] = projectOntoRecorded(recorded[key], live[key]);
|
|
10243
|
+
}
|
|
10244
|
+
return out;
|
|
10245
|
+
}
|
|
10246
|
+
function isPlainRecord$2(value) {
|
|
10247
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10248
|
+
}
|
|
10249
|
+
const LAMBDA_WEB_MAX_POLL_ATTEMPTS = 1200;
|
|
10250
|
+
function sleep$1(ms) {
|
|
10251
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
10252
|
+
}
|
|
10253
|
+
|
|
10254
|
+
//#endregion
|
|
10255
|
+
//#region src/provisioning/providers/lambda-web-function-revision-provider.ts
|
|
10256
|
+
const createRevisionLatch = new AmbiguousCreateLatch("lambda-web:CreateWebFunctionRevision");
|
|
10257
|
+
const revisionsCreatedByThisProcess = new RecentIdSet();
|
|
10258
|
+
var LambdaWebFunctionRevisionProvider = class {
|
|
10259
|
+
client;
|
|
10260
|
+
createClient;
|
|
10261
|
+
logger = getLogger().child("LambdaWebFunctionRevisionProvider");
|
|
10262
|
+
constructor() {
|
|
10263
|
+
this.client = getAwsClients().lambdaWeb;
|
|
10264
|
+
}
|
|
10265
|
+
handledProperties = /* @__PURE__ */ new Map([["AWS::Lambda::WebFunctionRevision", /* @__PURE__ */ new Set([
|
|
10266
|
+
"FunctionName",
|
|
10267
|
+
"Description",
|
|
10268
|
+
"KmsKeyArn",
|
|
10269
|
+
"BuildConfig",
|
|
10270
|
+
"ServiceConfig"
|
|
10271
|
+
])]]);
|
|
10272
|
+
unhandledByDesign = /* @__PURE__ */ new Map([["AWS::Lambda::WebFunctionRevision", /* @__PURE__ */ new Map([
|
|
10273
|
+
["FunctionArn", "AWS-managed read-only attribute"],
|
|
10274
|
+
["RevisionId", "AWS-managed read-only attribute"],
|
|
10275
|
+
["RevisionArn", "AWS-managed read-only attribute (primaryIdentifier / physical id)"],
|
|
10276
|
+
["State", "AWS-managed read-only attribute"],
|
|
10277
|
+
["StateReason", "AWS-managed read-only attribute"],
|
|
10278
|
+
["CreatedAt", "AWS-managed read-only attribute"]
|
|
10279
|
+
])]]);
|
|
10280
|
+
getMinResourceTimeoutMs() {
|
|
10281
|
+
return LAMBDA_WEB_MAX_POLL_ATTEMPTS * 500;
|
|
10282
|
+
}
|
|
10283
|
+
async create(logicalId, resourceType, properties, context) {
|
|
10284
|
+
this.logger.debug(safeMsg`Creating Lambda web function revision ${logicalId}`);
|
|
10285
|
+
const input = this.buildCreateInput(logicalId, resourceType, properties, context);
|
|
10286
|
+
const log = createMaskedLogSinks(this.logger, context?.maskSecrets);
|
|
10287
|
+
let createdArn;
|
|
10288
|
+
try {
|
|
10289
|
+
const orphanWindow = createRevisionLatch.take(logicalId);
|
|
10290
|
+
if (orphanWindow !== void 0) await this.reportPossibleRevisionOrphans(logicalId, orphanWindow, log, input.functionName);
|
|
10291
|
+
const createClient = await this.getCreateClient();
|
|
10292
|
+
const attemptStartMs = Date.now();
|
|
10293
|
+
let response;
|
|
10294
|
+
try {
|
|
10295
|
+
response = await createClient.send(new CreateWebFunctionRevisionCommand(input));
|
|
10296
|
+
} catch (error) {
|
|
10297
|
+
createRevisionLatch.noteFailure(logicalId, error, attemptStartMs, orphanWindow);
|
|
10298
|
+
throw error;
|
|
10299
|
+
}
|
|
10300
|
+
createdArn = response.revisionArn;
|
|
10301
|
+
if (createdArn) revisionsCreatedByThisProcess.add(createdArn);
|
|
10302
|
+
const replayWindow = replayedSendWindow(response, attemptStartMs);
|
|
10303
|
+
if (replayWindow !== void 0) await this.reportPossibleRevisionOrphans(logicalId, replayWindow, log, input.functionName);
|
|
10304
|
+
if (!createdArn || !response.revisionId) throw new ProvisioningError(`CreateWebFunctionRevision succeeded but returned no revision ARN for ${logicalIdShown(logicalId)}`, resourceType, logicalId);
|
|
10305
|
+
const active = await this.waitForActive(input.functionName, createdArn, logicalId);
|
|
10306
|
+
return {
|
|
10307
|
+
physicalId: createdArn,
|
|
10308
|
+
attributes: buildAttributes$2(active)
|
|
10309
|
+
};
|
|
10310
|
+
} catch (error) {
|
|
10311
|
+
const thrown = this.wrapError("create", logicalId, resourceType, void 0, error);
|
|
10312
|
+
let leftBehindArn = createdArn;
|
|
10313
|
+
if (leftBehindArn) try {
|
|
10314
|
+
await this.delete(logicalId, leftBehindArn, resourceType);
|
|
10315
|
+
leftBehindArn = void 0;
|
|
10316
|
+
} catch (cleanupError) {
|
|
10317
|
+
log.warn(safeMsg`Failed to delete partially-created Lambda web function revision ${logicalId}: ${describeAwsFailure(cleanupError).detail}. The failed deploy records it for \`cdkd rollback --revert-failed\`, or delete it by hand`);
|
|
10318
|
+
}
|
|
10319
|
+
if (leftBehindArn) {
|
|
10320
|
+
markCreatedBeforeFailure(thrown, logicalId, resourceType, leftBehindArn);
|
|
10321
|
+
markNonRetryable(thrown);
|
|
10322
|
+
}
|
|
10323
|
+
throw thrown;
|
|
10324
|
+
}
|
|
10325
|
+
}
|
|
10326
|
+
getCreateClient() {
|
|
10327
|
+
this.createClient ??= this.client.config.region().then((region) => withoutServerErrorRetries(new LambdaWebClient({
|
|
10328
|
+
...ambientClientDefaults(),
|
|
10329
|
+
region
|
|
10330
|
+
})), (error) => {
|
|
10331
|
+
this.createClient = void 0;
|
|
10332
|
+
throw error;
|
|
10333
|
+
});
|
|
10334
|
+
return this.createClient;
|
|
10335
|
+
}
|
|
10336
|
+
async reportPossibleRevisionOrphans(logicalId, window, log, functionName) {
|
|
10337
|
+
const aws = pasteableAwsCommand(log.mask);
|
|
10338
|
+
const regionArg = await orphanCommandRegionArg(this.client, aws);
|
|
10339
|
+
await reportPossibleOrphans(logicalId, window, log, {
|
|
10340
|
+
action: "CreateWebFunctionRevision",
|
|
10341
|
+
service: "Lambda",
|
|
10342
|
+
listAction: "ListWebFunctionRevisions",
|
|
10343
|
+
subject: `a revision of web function ${log.value(functionName)}`,
|
|
10344
|
+
noun: "revision(s)",
|
|
10345
|
+
list: () => collectOrphanIds(async (token) => {
|
|
10346
|
+
const page = await this.client.send(new ListWebFunctionRevisionsCommand({
|
|
10347
|
+
functionName,
|
|
10348
|
+
...token && { nextToken: token }
|
|
10349
|
+
}));
|
|
10350
|
+
return {
|
|
10351
|
+
items: page.revisions ?? [],
|
|
10352
|
+
next: page.nextToken
|
|
10353
|
+
};
|
|
10354
|
+
}, (item) => item.revisionArn && isInsideWindow(item.createdAt, window) && !revisionsCreatedByThisProcess.has(item.revisionArn) ? item.revisionArn : void 0),
|
|
10355
|
+
inspect: (id) => aws`aws cloudcontrol get-resource --type-name AWS::Lambda::WebFunctionRevision --identifier ${id}${regionArg}`.render(),
|
|
10356
|
+
remove: (id) => aws`aws cloudcontrol delete-resource --type-name AWS::Lambda::WebFunctionRevision --identifier ${id}${regionArg}`.render()
|
|
10357
|
+
});
|
|
10358
|
+
}
|
|
10359
|
+
async update(logicalId, physicalId, resourceType, _properties, _previousProperties, context) {
|
|
10360
|
+
assertRegionMatch(context?.expectedRegion ? await this.client.config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update");
|
|
10361
|
+
return Promise.reject(new ResourceUpdateNotSupportedError(resourceType, logicalId, "A Lambda web function revision is immutable — every property is create-only and there is no update API, so any change creates a new revision. cdkd normally classifies such a change as a replacement, so reaching this path is unexpected; re-run the deploy."));
|
|
10362
|
+
}
|
|
10363
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
10364
|
+
this.logger.debug(safeMsg`Deleting Lambda web function revision ${logicalId}`);
|
|
10365
|
+
const parts = parseWebFunctionChildArn(physicalId, "revision");
|
|
10366
|
+
if (!parts) throw new ProvisioningError(`Cannot delete Lambda web function revision ${logicalIdShown(logicalId)}: its recorded id is not a revision ARN`, resourceType, logicalId, physicalId);
|
|
10367
|
+
try {
|
|
10368
|
+
try {
|
|
10369
|
+
await this.client.send(new DeleteWebFunctionRevisionCommand({
|
|
10370
|
+
functionName: parts.functionArn,
|
|
10371
|
+
revisionId: physicalId
|
|
10372
|
+
}));
|
|
10373
|
+
} catch (error) {
|
|
10374
|
+
if (error instanceof ResourceNotFoundException$9) {
|
|
10375
|
+
assertRegionMatch(await this.client.config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
10376
|
+
this.logger.debug(safeMsg`Lambda web function revision ${logicalId} does not exist, skipping deletion`);
|
|
10377
|
+
return;
|
|
10378
|
+
}
|
|
10379
|
+
throw error;
|
|
10380
|
+
}
|
|
10381
|
+
await this.waitForGone(parts.functionArn, physicalId, logicalId);
|
|
10382
|
+
} catch (error) {
|
|
10383
|
+
throw this.wrapError("delete", logicalId, resourceType, physicalId, error);
|
|
10384
|
+
}
|
|
10385
|
+
}
|
|
10386
|
+
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
10387
|
+
const parts = parseWebFunctionChildArn(physicalId, "revision");
|
|
10388
|
+
if (attributeName === "RevisionArn") return physicalId;
|
|
10389
|
+
if (attributeName === "RevisionId" && parts) return parts.childId;
|
|
10390
|
+
if (attributeName === "FunctionArn" && parts) return parts.functionArn;
|
|
10391
|
+
if (!parts) return void 0;
|
|
10392
|
+
return buildAttributes$2(await this.client.send(new GetWebFunctionRevisionCommand({
|
|
10393
|
+
functionName: parts.functionArn,
|
|
10394
|
+
revisionId: physicalId
|
|
10395
|
+
})))[attributeName];
|
|
10396
|
+
}
|
|
10397
|
+
async import(input) {
|
|
10398
|
+
const arn = input.knownPhysicalId;
|
|
10399
|
+
if (!arn) return null;
|
|
10400
|
+
const parts = parseWebFunctionChildArn(arn, "revision");
|
|
10401
|
+
if (!parts) throw new Error(`--resource override for ${logicalIdShown(input.logicalId)} must be a Lambda web function revision ARN (got ${isPlainImportValue(arn) ? `'${arn}'` : VALUE_NOT_SHOWN}); use the arn:...:web-function/<name>/revision/<id> ARN.`);
|
|
10402
|
+
try {
|
|
10403
|
+
return {
|
|
10404
|
+
physicalId: arn,
|
|
10405
|
+
attributes: buildAttributes$2(await this.client.send(new GetWebFunctionRevisionCommand({
|
|
10406
|
+
functionName: parts.functionArn,
|
|
10407
|
+
revisionId: arn
|
|
10408
|
+
})))
|
|
10409
|
+
};
|
|
10410
|
+
} catch (error) {
|
|
10411
|
+
if (error instanceof ResourceNotFoundException$9) return null;
|
|
10412
|
+
throw error;
|
|
10413
|
+
}
|
|
10414
|
+
}
|
|
10415
|
+
async readCurrentState(physicalId, _logicalId, _resourceType, properties) {
|
|
10416
|
+
const parts = parseWebFunctionChildArn(physicalId, "revision");
|
|
10417
|
+
if (!parts) return void 0;
|
|
10418
|
+
let resp;
|
|
10419
|
+
try {
|
|
10420
|
+
resp = await this.client.send(new GetWebFunctionRevisionCommand({
|
|
10421
|
+
functionName: parts.functionArn,
|
|
10422
|
+
revisionId: physicalId
|
|
10423
|
+
}));
|
|
10424
|
+
} catch (error) {
|
|
10425
|
+
if (error instanceof ResourceNotFoundException$9) return RESOURCE_NOT_FOUND;
|
|
10426
|
+
throw error;
|
|
10427
|
+
}
|
|
10428
|
+
const live = { FunctionName: recordedFunctionNameSpelling(properties?.["FunctionName"], resp.functionArn ?? parts.functionArn) };
|
|
10429
|
+
if (resp.description !== void 0) live["Description"] = resp.description;
|
|
10430
|
+
if (resp.kmsKeyArn !== void 0) live["KmsKeyArn"] = resp.kmsKeyArn;
|
|
10431
|
+
if (resp.buildConfig) live["BuildConfig"] = buildConfigToCfn(resp.buildConfig);
|
|
10432
|
+
if (resp.serviceConfig) live["ServiceConfig"] = serviceConfigToCfn(resp.serviceConfig);
|
|
10433
|
+
if (!properties) return live;
|
|
10434
|
+
const out = { FunctionName: live["FunctionName"] };
|
|
10435
|
+
for (const key of [
|
|
10436
|
+
"Description",
|
|
10437
|
+
"KmsKeyArn",
|
|
10438
|
+
"BuildConfig",
|
|
10439
|
+
"ServiceConfig"
|
|
10440
|
+
]) if (key in live) out[key] = projectOntoRecorded(properties[key], live[key]);
|
|
10441
|
+
return out;
|
|
10442
|
+
}
|
|
10443
|
+
buildCreateInput(logicalId, resourceType, properties, context) {
|
|
10444
|
+
const fail = (message) => {
|
|
10445
|
+
throw new ProvisioningError(`${message} for Lambda web function revision ${logicalIdShown(logicalId)}`, resourceType, logicalId);
|
|
10446
|
+
};
|
|
10447
|
+
const functionName = properties["FunctionName"];
|
|
10448
|
+
if (typeof functionName !== "string" || functionName === "") fail("FunctionName must be a non-empty string");
|
|
10449
|
+
const build = properties["BuildConfig"];
|
|
10450
|
+
if (!isPlainRecord$2(build)) fail("BuildConfig must be an object");
|
|
10451
|
+
const code = build["CodeConfig"];
|
|
10452
|
+
const s3 = isPlainRecord$2(code) ? code["S3Object"] : void 0;
|
|
10453
|
+
if (!isPlainRecord$2(s3) || typeof s3["Bucket"] !== "string" || typeof s3["Key"] !== "string") fail("BuildConfig.CodeConfig.S3Object.Bucket and .Key are required strings");
|
|
10454
|
+
const runtimeConfig = build["RuntimeConfig"];
|
|
10455
|
+
const runtime = isPlainRecord$2(runtimeConfig) ? runtimeConfig["Runtime"] : void 0;
|
|
10456
|
+
if (typeof runtime !== "string") fail("BuildConfig.RuntimeConfig.Runtime is a required string");
|
|
10457
|
+
const service = properties["ServiceConfig"];
|
|
10458
|
+
if (!isPlainRecord$2(service) || typeof service["ExecutionRoleArn"] !== "string") fail("ServiceConfig.ExecutionRoleArn is a required string");
|
|
10459
|
+
const s3Object = s3;
|
|
10460
|
+
const input = {
|
|
10461
|
+
functionName,
|
|
10462
|
+
buildConfig: {
|
|
10463
|
+
codeConfig: { s3Object: {
|
|
10464
|
+
bucket: s3Object["Bucket"],
|
|
10465
|
+
key: s3Object["Key"],
|
|
10466
|
+
...typeof s3Object["VersionId"] === "string" ? { versionId: s3Object["VersionId"] } : {}
|
|
10467
|
+
} },
|
|
10468
|
+
runtimeConfig: { runtime }
|
|
10469
|
+
},
|
|
10470
|
+
serviceConfig: this.buildServiceConfig(service, fail, context)
|
|
10471
|
+
};
|
|
10472
|
+
if (typeof properties["Description"] === "string") input.description = properties["Description"];
|
|
10473
|
+
if (typeof properties["KmsKeyArn"] === "string") input.kmsKeyArn = properties["KmsKeyArn"];
|
|
10474
|
+
return input;
|
|
10475
|
+
}
|
|
10476
|
+
buildServiceConfig(service, fail, context) {
|
|
10477
|
+
const out = { executionRoleArn: service["ExecutionRoleArn"] };
|
|
10478
|
+
const integer = (key) => {
|
|
10479
|
+
const raw = service[key];
|
|
10480
|
+
if (raw === void 0) return void 0;
|
|
10481
|
+
const n = coerceCfnInteger(raw);
|
|
10482
|
+
if (n !== void 0) return n;
|
|
10483
|
+
const message = `ServiceConfig.${key} must be an integer`;
|
|
10484
|
+
if (context?.replayingState) {
|
|
10485
|
+
this.logger.warn(safeMsg`${message}; omitting it while replaying a state record`);
|
|
10486
|
+
return;
|
|
10487
|
+
}
|
|
10488
|
+
return fail(message);
|
|
10489
|
+
};
|
|
10490
|
+
const timeoutSeconds = integer("TimeoutSeconds");
|
|
10491
|
+
if (timeoutSeconds !== void 0) out.timeoutSeconds = timeoutSeconds;
|
|
10492
|
+
const maxConcurrencyPerEnvironment = integer("MaxConcurrencyPerEnvironment");
|
|
10493
|
+
if (maxConcurrencyPerEnvironment !== void 0) out.maxConcurrencyPerEnvironment = maxConcurrencyPerEnvironment;
|
|
10494
|
+
if (typeof service["EgressNetworkConnectorArn"] === "string") out.egressNetworkConnectorArn = service["EgressNetworkConnectorArn"];
|
|
10495
|
+
const env = service["EnvironmentVariables"];
|
|
10496
|
+
if (env !== void 0) {
|
|
10497
|
+
if (isPlainRecord$2(env) && Object.values(env).every((v) => typeof v === "string")) out.environmentVariables = { ...env };
|
|
10498
|
+
else if (context?.replayingState) this.logger.warn(safeMsg`ServiceConfig.EnvironmentVariables must be an object of string values; omitting it while replaying a state record`);
|
|
10499
|
+
else fail("ServiceConfig.EnvironmentVariables must be an object of string values");
|
|
10500
|
+
}
|
|
10501
|
+
const telemetry = service["TelemetryConfig"];
|
|
10502
|
+
if (isPlainRecord$2(telemetry)) {
|
|
10503
|
+
const telemetryConfig = {};
|
|
10504
|
+
const logging = telemetry["LoggingConfig"];
|
|
10505
|
+
if (isPlainRecord$2(logging)) {
|
|
10506
|
+
const loggingConfig = {};
|
|
10507
|
+
if (typeof logging["LogGroup"] === "string") loggingConfig.logGroup = logging["LogGroup"];
|
|
10508
|
+
if (typeof logging["ApplicationLogLevel"] === "string") loggingConfig.applicationLogLevel = logging["ApplicationLogLevel"];
|
|
10509
|
+
if (typeof logging["SystemLogLevel"] === "string") loggingConfig.systemLogLevel = logging["SystemLogLevel"];
|
|
10510
|
+
telemetryConfig.loggingConfig = loggingConfig;
|
|
10511
|
+
}
|
|
10512
|
+
out.telemetryConfig = telemetryConfig;
|
|
10513
|
+
}
|
|
10514
|
+
return out;
|
|
10515
|
+
}
|
|
10516
|
+
async waitForActive(functionName, revisionArn, logicalId) {
|
|
10517
|
+
for (let attempt = 1; attempt <= LAMBDA_WEB_MAX_POLL_ATTEMPTS; attempt++) {
|
|
10518
|
+
const resp = await this.client.send(new GetWebFunctionRevisionCommand({
|
|
10519
|
+
functionName,
|
|
10520
|
+
revisionId: revisionArn
|
|
10521
|
+
}));
|
|
10522
|
+
if (resp.state === "Active") return resp;
|
|
10523
|
+
if (resp.state === "Failed") {
|
|
10524
|
+
const errors = (resp.errors ?? []).map((e) => `${e.errorCode ?? ""} ${e.errorMessage ?? ""}`.trim());
|
|
10525
|
+
throw new Error(`Lambda web function revision ${logicalIdShown(logicalId)} entered Failed: ${resp.stateReason ?? "no reason given"}` + (errors.length > 0 ? ` (${errors.join("; ")})` : ""));
|
|
10526
|
+
}
|
|
10527
|
+
await sleep$1(500);
|
|
10528
|
+
}
|
|
10529
|
+
throw new Error(`Lambda web function revision ${logicalIdShown(logicalId)} did not become Active within ${LAMBDA_WEB_MAX_POLL_ATTEMPTS * 500 / 1e3}s.`);
|
|
10530
|
+
}
|
|
10531
|
+
async waitForGone(functionName, revisionArn, logicalId) {
|
|
10532
|
+
for (let attempt = 1; attempt <= LAMBDA_WEB_MAX_POLL_ATTEMPTS; attempt++) {
|
|
10533
|
+
try {
|
|
10534
|
+
await this.client.send(new GetWebFunctionRevisionCommand({
|
|
10535
|
+
functionName,
|
|
10536
|
+
revisionId: revisionArn
|
|
10537
|
+
}));
|
|
10538
|
+
} catch (error) {
|
|
10539
|
+
if (error instanceof ResourceNotFoundException$9) return;
|
|
10540
|
+
throw error;
|
|
10541
|
+
}
|
|
10542
|
+
await sleep$1(500);
|
|
10543
|
+
}
|
|
10544
|
+
throw new Error(`Lambda web function revision ${logicalIdShown(logicalId)} was not fully deleted within ${LAMBDA_WEB_MAX_POLL_ATTEMPTS * 500 / 1e3}s.`);
|
|
10545
|
+
}
|
|
10546
|
+
wrapError(operation, logicalId, resourceType, physicalId, error) {
|
|
10547
|
+
if (error instanceof ProvisioningError) return error;
|
|
10548
|
+
const cause = error instanceof Error ? error : void 0;
|
|
10549
|
+
return new ProvisioningError(`Failed to ${operation} Lambda web function revision ${logicalIdShown(logicalId)}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
10550
|
+
}
|
|
10551
|
+
};
|
|
10552
|
+
function buildAttributes$2(resp) {
|
|
10553
|
+
return definedAttributes({
|
|
10554
|
+
RevisionArn: resp.revisionArn,
|
|
10555
|
+
RevisionId: resp.revisionId,
|
|
10556
|
+
FunctionArn: resp.functionArn,
|
|
10557
|
+
State: resp.state,
|
|
10558
|
+
StateReason: resp.stateReason,
|
|
10559
|
+
CreatedAt: resp.createdAt?.toISOString()
|
|
10560
|
+
});
|
|
10561
|
+
}
|
|
10562
|
+
function buildConfigToCfn(config) {
|
|
10563
|
+
const out = {};
|
|
10564
|
+
const s3 = config.codeConfig && "s3Object" in config.codeConfig ? config.codeConfig.s3Object : void 0;
|
|
10565
|
+
if (s3) {
|
|
10566
|
+
const S3Object = {
|
|
10567
|
+
Bucket: s3.bucket,
|
|
10568
|
+
Key: s3.key
|
|
10569
|
+
};
|
|
10570
|
+
if (s3.versionId !== void 0) S3Object["VersionId"] = s3.versionId;
|
|
10571
|
+
out["CodeConfig"] = { S3Object };
|
|
10572
|
+
}
|
|
10573
|
+
if (config.runtimeConfig) out["RuntimeConfig"] = { Runtime: config.runtimeConfig.runtime };
|
|
10574
|
+
return out;
|
|
10575
|
+
}
|
|
10576
|
+
function serviceConfigToCfn(config) {
|
|
10577
|
+
const out = { ExecutionRoleArn: config.executionRoleArn };
|
|
10578
|
+
if (config.timeoutSeconds !== void 0) out["TimeoutSeconds"] = config.timeoutSeconds;
|
|
10579
|
+
if (config.maxConcurrencyPerEnvironment !== void 0) out["MaxConcurrencyPerEnvironment"] = config.maxConcurrencyPerEnvironment;
|
|
10580
|
+
if (config.egressNetworkConnectorArn !== void 0) out["EgressNetworkConnectorArn"] = config.egressNetworkConnectorArn;
|
|
10581
|
+
if (config.environmentVariables !== void 0) out["EnvironmentVariables"] = { ...config.environmentVariables };
|
|
10582
|
+
const logging = config.telemetryConfig?.loggingConfig;
|
|
10583
|
+
if (logging) {
|
|
10584
|
+
const LoggingConfig = {};
|
|
10585
|
+
if (logging.logGroup !== void 0) LoggingConfig["LogGroup"] = logging.logGroup;
|
|
10586
|
+
if (logging.applicationLogLevel !== void 0) LoggingConfig["ApplicationLogLevel"] = logging.applicationLogLevel;
|
|
10587
|
+
if (logging.systemLogLevel !== void 0) LoggingConfig["SystemLogLevel"] = logging.systemLogLevel;
|
|
10588
|
+
out["TelemetryConfig"] = { LoggingConfig };
|
|
10589
|
+
}
|
|
10590
|
+
return out;
|
|
10591
|
+
}
|
|
10592
|
+
|
|
10593
|
+
//#endregion
|
|
10594
|
+
//#region src/provisioning/providers/lambda-web-function-endpoint-provider.ts
|
|
10595
|
+
var LambdaWebFunctionEndpointProvider = class {
|
|
10596
|
+
client;
|
|
10597
|
+
logger = getLogger().child("LambdaWebFunctionEndpointProvider");
|
|
10598
|
+
constructor() {
|
|
10599
|
+
this.client = getAwsClients().lambdaWeb;
|
|
10600
|
+
}
|
|
10601
|
+
handledProperties = /* @__PURE__ */ new Map([["AWS::Lambda::WebFunctionEndpoint", /* @__PURE__ */ new Set([
|
|
10602
|
+
"FunctionName",
|
|
10603
|
+
"EndpointName",
|
|
10604
|
+
"Description",
|
|
10605
|
+
"EndpointType",
|
|
10606
|
+
"AuthType",
|
|
10607
|
+
"RevisionWeights",
|
|
10608
|
+
"Regions",
|
|
10609
|
+
"ScalingConfig",
|
|
10610
|
+
"ThrottleConfig"
|
|
10611
|
+
])]]);
|
|
10612
|
+
unhandledByDesign = /* @__PURE__ */ new Map([["AWS::Lambda::WebFunctionEndpoint", /* @__PURE__ */ new Map([
|
|
10613
|
+
["FunctionArn", "AWS-managed read-only attribute"],
|
|
10614
|
+
["EndpointArn", "AWS-managed read-only attribute (primaryIdentifier / physical id)"],
|
|
10615
|
+
["DomainName", "AWS-managed read-only attribute"],
|
|
10616
|
+
["State", "AWS-managed read-only attribute"],
|
|
10617
|
+
["StateReason", "AWS-managed read-only attribute"],
|
|
10618
|
+
["UpdateStatus", "AWS-managed read-only attribute"],
|
|
10619
|
+
["UpdateStatusReason", "AWS-managed read-only attribute"],
|
|
10620
|
+
["RegionalEndpoints", "AWS-managed read-only attribute"],
|
|
10621
|
+
["CreatedAt", "AWS-managed read-only attribute"],
|
|
10622
|
+
["UpdatedAt", "AWS-managed read-only attribute"]
|
|
10623
|
+
])]]);
|
|
10624
|
+
getMinResourceTimeoutMs() {
|
|
10625
|
+
return LAMBDA_WEB_MAX_POLL_ATTEMPTS * 500;
|
|
10626
|
+
}
|
|
10627
|
+
async create(logicalId, resourceType, properties, context) {
|
|
10628
|
+
this.logger.debug(safeMsg`Creating Lambda web function endpoint ${logicalId}`);
|
|
10629
|
+
const fail = this.refusal(logicalId, resourceType);
|
|
10630
|
+
const lenient = context?.replayingState === true;
|
|
10631
|
+
const functionName = properties["FunctionName"];
|
|
10632
|
+
const endpointName = properties["EndpointName"];
|
|
10633
|
+
const endpointType = properties["EndpointType"];
|
|
10634
|
+
const authType = properties["AuthType"];
|
|
10635
|
+
for (const [key, value] of [
|
|
10636
|
+
["FunctionName", functionName],
|
|
10637
|
+
["EndpointName", endpointName],
|
|
10638
|
+
["EndpointType", endpointType],
|
|
10639
|
+
["AuthType", authType]
|
|
10640
|
+
]) if (typeof value !== "string" || value === "") fail(`${key} must be a non-empty string`);
|
|
10641
|
+
const input = {
|
|
10642
|
+
functionName,
|
|
10643
|
+
endpointName,
|
|
10644
|
+
endpointType,
|
|
10645
|
+
authType
|
|
10646
|
+
};
|
|
10647
|
+
if (typeof properties["Description"] === "string") input.description = properties["Description"];
|
|
10648
|
+
const weights = readRevisionWeights(properties["RevisionWeights"], fail);
|
|
10649
|
+
if (weights !== void 0) input.revisionWeights = weights.map((w) => ({
|
|
10650
|
+
revisionId: w.RevisionId,
|
|
10651
|
+
weight: w.Weight
|
|
10652
|
+
}));
|
|
10653
|
+
if (properties["Regions"] !== void 0) {
|
|
10654
|
+
const regions = properties["Regions"];
|
|
10655
|
+
if (!Array.isArray(regions) || regions.some((r) => typeof r !== "string")) fail("Regions must be a list of strings");
|
|
10656
|
+
input.regions = [...regions];
|
|
10657
|
+
}
|
|
10658
|
+
const scaling = this.readIntegerBlock(properties["ScalingConfig"], "ScalingConfig", "MaxEnvironments", fail, lenient);
|
|
10659
|
+
if (scaling !== void 0) input.scalingConfig = scaling.present ? { maxEnvironments: scaling.n } : {};
|
|
10660
|
+
const throttle = this.readIntegerBlock(properties["ThrottleConfig"], "ThrottleConfig", "RateLimit", fail, lenient);
|
|
10661
|
+
if (throttle !== void 0) input.throttleConfig = throttle.present ? { rateLimit: throttle.n } : {};
|
|
10662
|
+
let createdArn;
|
|
10663
|
+
try {
|
|
10664
|
+
createdArn = (await this.client.send(new CreateWebFunctionEndpointCommand(input))).endpointArn;
|
|
10665
|
+
if (!createdArn) throw new ProvisioningError(`CreateWebFunctionEndpoint succeeded but returned no endpoint ARN for ${logicalIdShown(logicalId)}`, resourceType, logicalId);
|
|
10666
|
+
const settled = await this.waitForSettled(input.functionName, input.endpointName, logicalId, "create");
|
|
10667
|
+
return {
|
|
10668
|
+
physicalId: createdArn,
|
|
10669
|
+
attributes: buildAttributes$1(settled)
|
|
10670
|
+
};
|
|
10671
|
+
} catch (error) {
|
|
10672
|
+
const thrown = this.wrapError("create", logicalId, resourceType, void 0, error);
|
|
10673
|
+
if (createdArn) markCreatedBeforeFailure(thrown, logicalId, resourceType, createdArn);
|
|
10674
|
+
throw thrown;
|
|
10675
|
+
}
|
|
10676
|
+
}
|
|
10677
|
+
async update(logicalId, physicalId, resourceType, properties, _previousProperties, context) {
|
|
10678
|
+
assertRegionMatch(context?.expectedRegion ? await this.client.config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update");
|
|
10679
|
+
const parts = parseWebFunctionChildArn(physicalId, "endpoint");
|
|
10680
|
+
if (!parts) throw new ProvisioningError(`Cannot update Lambda web function endpoint ${logicalIdShown(logicalId)}: its recorded id is not an endpoint ARN`, resourceType, logicalId, physicalId);
|
|
10681
|
+
const fail = this.refusal(logicalId, resourceType, physicalId);
|
|
10682
|
+
const lenient = context?.replayingState === true || context?.desiredFromAwsReadback === true;
|
|
10683
|
+
const input = {
|
|
10684
|
+
functionName: parts.functionArn,
|
|
10685
|
+
endpointName: parts.childId,
|
|
10686
|
+
description: typeof properties["Description"] === "string" ? properties["Description"] : ""
|
|
10687
|
+
};
|
|
10688
|
+
if (typeof properties["AuthType"] === "string") input.authType = properties["AuthType"];
|
|
10689
|
+
const weights = readRevisionWeights(properties["RevisionWeights"], fail);
|
|
10690
|
+
if (weights !== void 0) input.revisionWeights = weights.map((w) => ({
|
|
10691
|
+
revisionId: w.RevisionId,
|
|
10692
|
+
weight: w.Weight
|
|
10693
|
+
}));
|
|
10694
|
+
else if (!lenient) fail("RevisionWeights is required; AWS keeps routing to the current revisions when it is removed");
|
|
10695
|
+
const scaling = this.readIntegerBlock(properties["ScalingConfig"], "ScalingConfig", "MaxEnvironments", fail, lenient);
|
|
10696
|
+
if (properties["ScalingConfig"] === void 0) input.scalingConfig = {};
|
|
10697
|
+
else if (scaling !== void 0) input.scalingConfig = scaling.present ? { maxEnvironments: scaling.n } : {};
|
|
10698
|
+
const throttle = this.readIntegerBlock(properties["ThrottleConfig"], "ThrottleConfig", "RateLimit", fail, lenient);
|
|
10699
|
+
if (properties["ThrottleConfig"] === void 0) input.throttleConfig = {};
|
|
10700
|
+
else if (throttle !== void 0) input.throttleConfig = throttle.present ? { rateLimit: throttle.n } : {};
|
|
10701
|
+
try {
|
|
10702
|
+
await this.client.send(new UpdateWebFunctionEndpointCommand(input));
|
|
10703
|
+
return {
|
|
10704
|
+
physicalId,
|
|
10705
|
+
wasReplaced: false,
|
|
10706
|
+
attributes: buildAttributes$1(await this.waitForSettled(parts.functionArn, parts.childId, logicalId, "update", input.revisionWeights))
|
|
10707
|
+
};
|
|
10708
|
+
} catch (error) {
|
|
10709
|
+
throw this.wrapError("update", logicalId, resourceType, physicalId, error);
|
|
10710
|
+
}
|
|
10711
|
+
}
|
|
10712
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
10713
|
+
this.logger.debug(safeMsg`Deleting Lambda web function endpoint ${logicalId}`);
|
|
10714
|
+
const parts = parseWebFunctionChildArn(physicalId, "endpoint");
|
|
10715
|
+
if (!parts) throw new ProvisioningError(`Cannot delete Lambda web function endpoint ${logicalIdShown(logicalId)}: its recorded id is not an endpoint ARN`, resourceType, logicalId, physicalId);
|
|
10716
|
+
try {
|
|
10717
|
+
try {
|
|
10718
|
+
await this.client.send(new DeleteWebFunctionEndpointCommand({
|
|
10719
|
+
functionName: parts.functionArn,
|
|
10720
|
+
endpointName: parts.childId
|
|
10721
|
+
}));
|
|
10722
|
+
} catch (error) {
|
|
10723
|
+
if (error instanceof ResourceNotFoundException$9) {
|
|
10724
|
+
assertRegionMatch(await this.client.config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
10725
|
+
this.logger.debug(safeMsg`Lambda web function endpoint ${logicalId} does not exist, skipping deletion`);
|
|
10726
|
+
return;
|
|
10727
|
+
}
|
|
10728
|
+
throw error;
|
|
10729
|
+
}
|
|
10730
|
+
await this.waitForGone(parts.functionArn, parts.childId, logicalId);
|
|
10731
|
+
} catch (error) {
|
|
10732
|
+
throw this.wrapError("delete", logicalId, resourceType, physicalId, error);
|
|
10733
|
+
}
|
|
10734
|
+
}
|
|
10735
|
+
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
10736
|
+
if (attributeName === "EndpointArn") return physicalId;
|
|
10737
|
+
const parts = parseWebFunctionChildArn(physicalId, "endpoint");
|
|
10738
|
+
if (!parts) return void 0;
|
|
10739
|
+
if (attributeName === "FunctionArn") return parts.functionArn;
|
|
10740
|
+
return buildAttributes$1(await this.client.send(new GetWebFunctionEndpointCommand({
|
|
10741
|
+
functionName: parts.functionArn,
|
|
10742
|
+
endpointName: parts.childId
|
|
10743
|
+
})))[attributeName];
|
|
10744
|
+
}
|
|
10745
|
+
async import(input) {
|
|
10746
|
+
let functionName;
|
|
10747
|
+
let endpointName;
|
|
10748
|
+
if (input.knownPhysicalId) {
|
|
10749
|
+
const parts = parseWebFunctionChildArn(input.knownPhysicalId, "endpoint");
|
|
10750
|
+
if (!parts) throw new Error(`--resource override for ${logicalIdShown(input.logicalId)} must be a Lambda web function endpoint ARN (got ${isPlainImportValue(input.knownPhysicalId) ? `'${input.knownPhysicalId}'` : VALUE_NOT_SHOWN}); use the arn:...:web-function/<name>/endpoint/<endpoint> ARN.`);
|
|
10751
|
+
functionName = parts.functionArn;
|
|
10752
|
+
endpointName = parts.childId;
|
|
10753
|
+
} else {
|
|
10754
|
+
const props = input.properties ?? {};
|
|
10755
|
+
if (typeof props["FunctionName"] !== "string" || typeof props["EndpointName"] !== "string") return null;
|
|
10756
|
+
functionName = props["FunctionName"];
|
|
10757
|
+
endpointName = props["EndpointName"];
|
|
10758
|
+
}
|
|
10759
|
+
try {
|
|
10760
|
+
const resp = await this.client.send(new GetWebFunctionEndpointCommand({
|
|
10761
|
+
functionName,
|
|
10762
|
+
endpointName
|
|
10763
|
+
}));
|
|
10764
|
+
if (!resp.endpointArn) return null;
|
|
10765
|
+
return {
|
|
10766
|
+
physicalId: resp.endpointArn,
|
|
10767
|
+
attributes: buildAttributes$1(resp)
|
|
10768
|
+
};
|
|
10769
|
+
} catch (error) {
|
|
10770
|
+
if (error instanceof ResourceNotFoundException$9) return null;
|
|
10771
|
+
throw error;
|
|
10772
|
+
}
|
|
10773
|
+
}
|
|
10774
|
+
async readCurrentState(physicalId, _logicalId, _resourceType, properties) {
|
|
10775
|
+
const parts = parseWebFunctionChildArn(physicalId, "endpoint");
|
|
10776
|
+
if (!parts) return void 0;
|
|
10777
|
+
let resp;
|
|
10778
|
+
try {
|
|
10779
|
+
resp = await this.client.send(new GetWebFunctionEndpointCommand({
|
|
10780
|
+
functionName: parts.functionArn,
|
|
10781
|
+
endpointName: parts.childId
|
|
10782
|
+
}));
|
|
10783
|
+
} catch (error) {
|
|
10784
|
+
if (error instanceof ResourceNotFoundException$9) return RESOURCE_NOT_FOUND;
|
|
10785
|
+
throw error;
|
|
10786
|
+
}
|
|
10787
|
+
const live = {
|
|
10788
|
+
FunctionName: recordedFunctionNameSpelling(properties?.["FunctionName"], resp.functionArn ?? parts.functionArn),
|
|
10789
|
+
EndpointName: resp.endpointName ?? parts.childId
|
|
10790
|
+
};
|
|
10791
|
+
if (resp.description !== void 0) live["Description"] = resp.description;
|
|
10792
|
+
if (resp.endpointType !== void 0) live["EndpointType"] = resp.endpointType;
|
|
10793
|
+
if (resp.authType !== void 0) live["AuthType"] = resp.authType;
|
|
10794
|
+
if (resp.revisionWeights !== void 0) live["RevisionWeights"] = resp.revisionWeights.map((w) => ({
|
|
10795
|
+
RevisionId: w.revisionId,
|
|
10796
|
+
Weight: w.weight
|
|
10797
|
+
}));
|
|
10798
|
+
if (resp.regions !== void 0) live["Regions"] = [...resp.regions];
|
|
10799
|
+
if (resp.scalingConfig !== void 0) live["ScalingConfig"] = resp.scalingConfig.maxEnvironments !== void 0 ? { MaxEnvironments: resp.scalingConfig.maxEnvironments } : {};
|
|
10800
|
+
if (resp.throttleConfig !== void 0) live["ThrottleConfig"] = resp.throttleConfig.rateLimit !== void 0 ? { RateLimit: resp.throttleConfig.rateLimit } : {};
|
|
10801
|
+
if (!properties) return live;
|
|
10802
|
+
const out = {};
|
|
10803
|
+
for (const [key, value] of Object.entries(live)) out[key] = key === "ScalingConfig" || key === "ThrottleConfig" ? value : projectOntoRecorded(properties[key], value);
|
|
10804
|
+
return out;
|
|
10805
|
+
}
|
|
10806
|
+
refusal(logicalId, resourceType, physicalId) {
|
|
10807
|
+
return (message) => {
|
|
10808
|
+
throw new ProvisioningError(`${message} for Lambda web function endpoint ${logicalIdShown(logicalId)}`, resourceType, logicalId, physicalId);
|
|
10809
|
+
};
|
|
10810
|
+
}
|
|
10811
|
+
readIntegerBlock(value, blockKey, memberKey, fail, lenient) {
|
|
10812
|
+
if (value === void 0) return void 0;
|
|
10813
|
+
const bad = (message) => {
|
|
10814
|
+
if (lenient) {
|
|
10815
|
+
this.logger.warn(safeMsg`${message}; leaving the live ${blockKey} unchanged`);
|
|
10816
|
+
return;
|
|
10817
|
+
}
|
|
10818
|
+
return fail(message);
|
|
10819
|
+
};
|
|
10820
|
+
if (!isPlainRecord$2(value)) return bad(`${blockKey} must be an object`);
|
|
10821
|
+
if (value[memberKey] === void 0) return { present: false };
|
|
10822
|
+
const n = coerceCfnInteger(value[memberKey]);
|
|
10823
|
+
if (n === void 0) return bad(`${blockKey}.${memberKey} must be an integer`);
|
|
10824
|
+
return {
|
|
10825
|
+
present: true,
|
|
10826
|
+
n
|
|
10827
|
+
};
|
|
10828
|
+
}
|
|
10829
|
+
async waitForSettled(functionName, endpointName, logicalId, operation, sentWeights) {
|
|
10830
|
+
for (let attempt = 1; attempt <= LAMBDA_WEB_MAX_POLL_ATTEMPTS; attempt++) {
|
|
10831
|
+
let resp;
|
|
10832
|
+
try {
|
|
10833
|
+
resp = await this.client.send(new GetWebFunctionEndpointCommand({
|
|
10834
|
+
functionName,
|
|
10835
|
+
endpointName
|
|
10836
|
+
}));
|
|
10837
|
+
} catch (error) {
|
|
10838
|
+
if (operation === "create" && attempt <= 10 && error instanceof ResourceNotFoundException$9) {
|
|
10839
|
+
await sleep$1(500);
|
|
10840
|
+
continue;
|
|
10841
|
+
}
|
|
10842
|
+
throw error;
|
|
10843
|
+
}
|
|
10844
|
+
if (resp.state === "Failed") throw new Error(`Lambda web function endpoint ${logicalIdShown(logicalId)} entered Failed: ${resp.stateReason ?? "no reason given"}`);
|
|
10845
|
+
if (resp.updateStatus === "Failed") throw new Error(`Lambda web function endpoint ${logicalIdShown(logicalId)} ${operation} failed: ${resp.updateStatusReason ?? "no reason given"}`);
|
|
10846
|
+
if (resp.state === "Active" && resp.updateStatus !== "InProgress" && (sentWeights === void 0 || sameWeights(sentWeights, resp.revisionWeights))) return resp;
|
|
10847
|
+
await sleep$1(500);
|
|
10848
|
+
}
|
|
10849
|
+
throw new Error(`Lambda web function endpoint ${logicalIdShown(logicalId)} did not finish ${operation} within ${LAMBDA_WEB_MAX_POLL_ATTEMPTS * 500 / 1e3}s.`);
|
|
10850
|
+
}
|
|
10851
|
+
async waitForGone(functionName, endpointName, logicalId) {
|
|
10852
|
+
for (let attempt = 1; attempt <= LAMBDA_WEB_MAX_POLL_ATTEMPTS; attempt++) {
|
|
10853
|
+
try {
|
|
10854
|
+
await this.client.send(new GetWebFunctionEndpointCommand({
|
|
10855
|
+
functionName,
|
|
10856
|
+
endpointName
|
|
10857
|
+
}));
|
|
10858
|
+
} catch (error) {
|
|
10859
|
+
if (error instanceof ResourceNotFoundException$9) return;
|
|
10860
|
+
throw error;
|
|
10861
|
+
}
|
|
10862
|
+
await sleep$1(500);
|
|
10863
|
+
}
|
|
10864
|
+
throw new Error(`Lambda web function endpoint ${logicalIdShown(logicalId)} was not fully deleted within ${LAMBDA_WEB_MAX_POLL_ATTEMPTS * 500 / 1e3}s.`);
|
|
10865
|
+
}
|
|
10866
|
+
wrapError(operation, logicalId, resourceType, physicalId, error) {
|
|
10867
|
+
if (error instanceof ProvisioningError) return error;
|
|
10868
|
+
const cause = error instanceof Error ? error : void 0;
|
|
10869
|
+
return new ProvisioningError(`Failed to ${operation} Lambda web function endpoint ${logicalIdShown(logicalId)}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
10870
|
+
}
|
|
10871
|
+
};
|
|
10872
|
+
function readRevisionWeights(value, fail) {
|
|
10873
|
+
if (value === void 0) return void 0;
|
|
10874
|
+
if (!Array.isArray(value)) return fail("RevisionWeights must be a list");
|
|
10875
|
+
return value.map((entry, i) => {
|
|
10876
|
+
if (!isPlainRecord$2(entry) || typeof entry["RevisionId"] !== "string") return fail(`RevisionWeights[${i}].RevisionId must be a string`);
|
|
10877
|
+
const weight = coerceCfnInteger(entry["Weight"]);
|
|
10878
|
+
if (weight === void 0) return fail(`RevisionWeights[${i}].Weight must be an integer`);
|
|
10879
|
+
return {
|
|
10880
|
+
RevisionId: entry["RevisionId"],
|
|
10881
|
+
Weight: weight
|
|
10882
|
+
};
|
|
10883
|
+
});
|
|
10884
|
+
}
|
|
10885
|
+
function sameWeights(a, b) {
|
|
10886
|
+
if (b === void 0 || a.length !== b.length) return false;
|
|
10887
|
+
const key = (w) => `${w.revisionId ?? ""}=${w.weight ?? ""}`;
|
|
10888
|
+
const left = a.map(key).sort();
|
|
10889
|
+
const right = b.map(key).sort();
|
|
10890
|
+
return left.every((k, i) => k === right[i]);
|
|
10891
|
+
}
|
|
10892
|
+
function buildAttributes$1(resp) {
|
|
10893
|
+
return definedAttributes({
|
|
10894
|
+
EndpointArn: resp.endpointArn,
|
|
10895
|
+
FunctionArn: resp.functionArn,
|
|
10896
|
+
DomainName: resp.domainName,
|
|
10897
|
+
State: resp.state,
|
|
10898
|
+
StateReason: resp.stateReason,
|
|
10899
|
+
UpdateStatus: resp.updateStatus,
|
|
10900
|
+
UpdateStatusReason: resp.updateStatusReason,
|
|
10901
|
+
CreatedAt: resp.createdAt?.toISOString(),
|
|
10902
|
+
UpdatedAt: resp.updatedAt?.toISOString()
|
|
10903
|
+
});
|
|
10904
|
+
}
|
|
10905
|
+
|
|
10906
|
+
//#endregion
|
|
10907
|
+
//#region src/provisioning/providers/lambda-network-connector-provider.ts
|
|
10908
|
+
const POLL_INTERVAL_MS$2 = 1e3;
|
|
10909
|
+
const MAX_POLL_ATTEMPTS = 1200;
|
|
10910
|
+
var LambdaNetworkConnectorProvider = class {
|
|
10911
|
+
client;
|
|
10912
|
+
lambda;
|
|
10913
|
+
logger = getLogger().child("LambdaNetworkConnectorProvider");
|
|
10914
|
+
constructor() {
|
|
10915
|
+
const clients = getAwsClients();
|
|
10916
|
+
this.client = clients.lambdaCore;
|
|
10917
|
+
this.lambda = clients.lambda;
|
|
10918
|
+
}
|
|
10919
|
+
handledProperties = /* @__PURE__ */ new Map([["AWS::Lambda::NetworkConnector", /* @__PURE__ */ new Set([
|
|
10920
|
+
"Name",
|
|
10921
|
+
"Configuration",
|
|
10922
|
+
"OperatorRole",
|
|
10923
|
+
"Tags"
|
|
10924
|
+
])]]);
|
|
10925
|
+
unhandledByDesign = /* @__PURE__ */ new Map([["AWS::Lambda::NetworkConnector", /* @__PURE__ */ new Map([
|
|
10926
|
+
["Arn", "AWS-managed read-only attribute (primaryIdentifier / physical id)"],
|
|
10927
|
+
["State", "AWS-managed read-only attribute"],
|
|
10928
|
+
["LatestVersionArn", "AWS-managed read-only attribute"],
|
|
10929
|
+
["LatestVersion", "AWS-managed read-only attribute"]
|
|
10930
|
+
])]]);
|
|
10931
|
+
getMinResourceTimeoutMs() {
|
|
10932
|
+
return MAX_POLL_ATTEMPTS * POLL_INTERVAL_MS$2;
|
|
10933
|
+
}
|
|
10934
|
+
async create(logicalId, resourceType, properties, context) {
|
|
10935
|
+
this.logger.debug(safeMsg`Creating Lambda network connector ${logicalId}`);
|
|
10936
|
+
const tagList = refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId);
|
|
10937
|
+
const name = typeof properties["Name"] === "string" && properties["Name"] !== "" ? properties["Name"] : generateResourceName(logicalId, { maxLength: 64 });
|
|
10938
|
+
const vpc = this.readVpcEgress(properties, logicalId, resourceType, void 0);
|
|
10939
|
+
const createToken = acquireIdempotencyToken({
|
|
10940
|
+
scope: "CreateNetworkConnector",
|
|
10941
|
+
logicalId
|
|
10942
|
+
});
|
|
10943
|
+
const input = {
|
|
10944
|
+
Name: name,
|
|
10945
|
+
Configuration: { VpcEgressConfiguration: {
|
|
10946
|
+
SubnetIds: vpc.SubnetIds,
|
|
10947
|
+
SecurityGroupIds: vpc.SecurityGroupIds,
|
|
10948
|
+
NetworkProtocol: vpc.NetworkProtocol,
|
|
10949
|
+
AssociatedComputeResourceTypes: vpc.AssociatedComputeResourceTypes
|
|
10950
|
+
} },
|
|
10951
|
+
ClientToken: createToken.value
|
|
10952
|
+
};
|
|
10953
|
+
const operatorRole = this.readOperatorRole(properties, logicalId, resourceType, void 0, context);
|
|
10954
|
+
if (operatorRole !== void 0) input.OperatorRole = operatorRole;
|
|
10955
|
+
if (tagList.length > 0) input.Tags = Object.fromEntries(tagList.map((t) => [t.Key, t.Value]));
|
|
10956
|
+
let createdArn;
|
|
10957
|
+
try {
|
|
10958
|
+
createdArn = (await this.client.send(new CreateNetworkConnectorCommand(input))).Arn;
|
|
10959
|
+
if (!createdArn) throw new ProvisioningError(`CreateNetworkConnector succeeded but returned no ARN for ${logicalIdShown(logicalId)}`, resourceType, logicalId);
|
|
10960
|
+
const settled = await this.waitForSettled(createdArn, logicalId, "create");
|
|
10961
|
+
createToken.release();
|
|
10962
|
+
return {
|
|
10963
|
+
physicalId: createdArn,
|
|
10964
|
+
attributes: buildAttributes(settled)
|
|
10965
|
+
};
|
|
10966
|
+
} catch (error) {
|
|
10967
|
+
const thrown = this.wrapError("create", logicalId, resourceType, void 0, error);
|
|
10968
|
+
if (error instanceof TerminalConnectorStateError) markNonRetryable(thrown);
|
|
10969
|
+
if (createdArn) markCreatedBeforeFailure(thrown, logicalId, resourceType, createdArn);
|
|
10970
|
+
throw thrown;
|
|
10971
|
+
}
|
|
10972
|
+
}
|
|
10973
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
10974
|
+
assertRegionMatch(context?.expectedRegion ? await this.client.config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update");
|
|
10975
|
+
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
10976
|
+
const vpc = this.readVpcEgress(properties, logicalId, resourceType, physicalId);
|
|
10977
|
+
const updateRole = this.readOperatorRole(properties, logicalId, resourceType, physicalId, context);
|
|
10978
|
+
if (typeof previousProperties["OperatorRole"] === "string" && properties["OperatorRole"] === void 0 && context?.replayingState !== true && context?.desiredFromAwsReadback !== true) throw new ProvisioningError(`OperatorRole cannot be removed in place for Lambda network connector ${logicalIdShown(logicalId)}: cdkd sends no role when the template declares none, so the current one would stay attached. Set it to another role, or replace the connector (change its Name).`, resourceType, logicalId, physicalId);
|
|
10979
|
+
try {
|
|
10980
|
+
const configChanged = JSON.stringify(properties["Configuration"]) !== JSON.stringify(previousProperties["Configuration"]) || properties["OperatorRole"] !== previousProperties["OperatorRole"];
|
|
10981
|
+
await this.reconcileTags(physicalId, resourceType, logicalId, properties["Tags"], previousProperties["Tags"]);
|
|
10982
|
+
if (configChanged) await this.client.send(new UpdateNetworkConnectorCommand({
|
|
10983
|
+
Identifier: physicalId,
|
|
10984
|
+
Configuration: { VpcEgressConfiguration: {
|
|
10985
|
+
SubnetIds: vpc.SubnetIds,
|
|
10986
|
+
SecurityGroupIds: vpc.SecurityGroupIds,
|
|
10987
|
+
NetworkProtocol: vpc.NetworkProtocol,
|
|
10988
|
+
AssociatedComputeResourceTypes: vpc.AssociatedComputeResourceTypes
|
|
10989
|
+
} },
|
|
10990
|
+
...updateRole !== void 0 ? { OperatorRole: updateRole } : {},
|
|
10991
|
+
ClientToken: randomUUID()
|
|
10992
|
+
}));
|
|
10993
|
+
return {
|
|
10994
|
+
physicalId,
|
|
10995
|
+
wasReplaced: false,
|
|
10996
|
+
attributes: buildAttributes(configChanged ? await this.waitForSettled(physicalId, logicalId, "update") : await this.client.send(new GetNetworkConnectorCommand({ Identifier: physicalId })))
|
|
10997
|
+
};
|
|
10998
|
+
} catch (error) {
|
|
10999
|
+
throw this.wrapError("update", logicalId, resourceType, physicalId, error);
|
|
11000
|
+
}
|
|
11001
|
+
}
|
|
11002
|
+
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
11003
|
+
this.logger.debug(safeMsg`Deleting Lambda network connector ${logicalId}`);
|
|
11004
|
+
try {
|
|
11005
|
+
try {
|
|
11006
|
+
await this.client.send(new DeleteNetworkConnectorCommand({ Identifier: physicalId }));
|
|
11007
|
+
} catch (error) {
|
|
11008
|
+
if (error instanceof ResourceNotFoundException$10) {
|
|
11009
|
+
assertRegionMatch(await this.client.config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
11010
|
+
this.logger.debug(safeMsg`Lambda network connector ${logicalId} does not exist, skipping deletion`);
|
|
11011
|
+
return;
|
|
11012
|
+
}
|
|
11013
|
+
throw error;
|
|
11014
|
+
}
|
|
11015
|
+
await this.waitForGone(physicalId, logicalId);
|
|
11016
|
+
} catch (error) {
|
|
11017
|
+
throw this.wrapError("delete", logicalId, resourceType, physicalId, error);
|
|
11018
|
+
}
|
|
11019
|
+
}
|
|
11020
|
+
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
11021
|
+
if (attributeName === "Arn") return physicalId;
|
|
11022
|
+
return buildAttributes(await this.client.send(new GetNetworkConnectorCommand({ Identifier: physicalId })))[attributeName];
|
|
11023
|
+
}
|
|
11024
|
+
async import(input) {
|
|
11025
|
+
const props = input.properties ?? {};
|
|
11026
|
+
const identifier = input.knownPhysicalId ?? (typeof props["Name"] === "string" ? props["Name"] : void 0);
|
|
11027
|
+
if (!identifier) return null;
|
|
11028
|
+
try {
|
|
11029
|
+
const resp = await this.client.send(new GetNetworkConnectorCommand({ Identifier: identifier }));
|
|
11030
|
+
if (!resp.Arn) return null;
|
|
11031
|
+
return {
|
|
11032
|
+
physicalId: resp.Arn,
|
|
11033
|
+
attributes: buildAttributes(resp)
|
|
11034
|
+
};
|
|
11035
|
+
} catch (error) {
|
|
11036
|
+
if (error instanceof ResourceNotFoundException$10) return null;
|
|
11037
|
+
throw error;
|
|
11038
|
+
}
|
|
11039
|
+
}
|
|
11040
|
+
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
11041
|
+
let resp;
|
|
11042
|
+
try {
|
|
11043
|
+
resp = await this.client.send(new GetNetworkConnectorCommand({ Identifier: physicalId }));
|
|
11044
|
+
} catch (error) {
|
|
11045
|
+
if (error instanceof ResourceNotFoundException$10) return RESOURCE_NOT_FOUND;
|
|
11046
|
+
throw error;
|
|
11047
|
+
}
|
|
11048
|
+
const result = {};
|
|
11049
|
+
if (resp.Name !== void 0) result["Name"] = resp.Name;
|
|
11050
|
+
if (resp.OperatorRole !== void 0) result["OperatorRole"] = resp.OperatorRole;
|
|
11051
|
+
const vpc = resp.Configuration && "VpcEgressConfiguration" in resp.Configuration ? resp.Configuration.VpcEgressConfiguration : void 0;
|
|
11052
|
+
if (vpc) {
|
|
11053
|
+
const VpcEgressConfiguration = {};
|
|
11054
|
+
if (vpc.SubnetIds !== void 0) VpcEgressConfiguration["SubnetIds"] = [...vpc.SubnetIds];
|
|
11055
|
+
if (vpc.SecurityGroupIds !== void 0) VpcEgressConfiguration["SecurityGroupIds"] = [...vpc.SecurityGroupIds];
|
|
11056
|
+
if (vpc.NetworkProtocol !== void 0) VpcEgressConfiguration["NetworkProtocol"] = vpc.NetworkProtocol;
|
|
11057
|
+
if (vpc.AssociatedComputeResourceTypes !== void 0) VpcEgressConfiguration["AssociatedComputeResourceTypes"] = [...vpc.AssociatedComputeResourceTypes];
|
|
11058
|
+
result["Configuration"] = { VpcEgressConfiguration };
|
|
11059
|
+
}
|
|
11060
|
+
let tags;
|
|
11061
|
+
try {
|
|
11062
|
+
tags = await this.lambda.send(new ListTagsCommand({ Resource: physicalId }));
|
|
11063
|
+
} catch (error) {
|
|
11064
|
+
if (error instanceof ResourceNotFoundException) return RESOURCE_NOT_FOUND;
|
|
11065
|
+
throw error;
|
|
11066
|
+
}
|
|
11067
|
+
result["Tags"] = normalizeAwsTagsToCfn(tags.Tags);
|
|
11068
|
+
return result;
|
|
11069
|
+
}
|
|
11070
|
+
getDriftUnorderedPaths() {
|
|
11071
|
+
return [
|
|
11072
|
+
"Configuration.VpcEgressConfiguration.SubnetIds",
|
|
11073
|
+
"Configuration.VpcEgressConfiguration.SecurityGroupIds",
|
|
11074
|
+
"Configuration.VpcEgressConfiguration.AssociatedComputeResourceTypes"
|
|
11075
|
+
];
|
|
11076
|
+
}
|
|
11077
|
+
readVpcEgress(properties, logicalId, resourceType, physicalId) {
|
|
11078
|
+
const fail = (message) => {
|
|
11079
|
+
throw new ProvisioningError(`${message} for Lambda network connector ${logicalIdShown(logicalId)}`, resourceType, logicalId, physicalId);
|
|
11080
|
+
};
|
|
11081
|
+
const config = properties["Configuration"];
|
|
11082
|
+
const vpc = isPlainRecord$2(config) ? config["VpcEgressConfiguration"] : void 0;
|
|
11083
|
+
if (!isPlainRecord$2(vpc)) return fail("Configuration.VpcEgressConfiguration must be an object");
|
|
11084
|
+
const strings = (key) => {
|
|
11085
|
+
const value = vpc[key];
|
|
11086
|
+
if (value === void 0) return void 0;
|
|
11087
|
+
if (!Array.isArray(value) || value.some((v) => typeof v !== "string")) return fail(`Configuration.VpcEgressConfiguration.${key} must be a list of strings`);
|
|
11088
|
+
return [...value];
|
|
11089
|
+
};
|
|
11090
|
+
const subnetIds = strings("SubnetIds");
|
|
11091
|
+
const securityGroupIds = strings("SecurityGroupIds");
|
|
11092
|
+
const types = strings("AssociatedComputeResourceTypes");
|
|
11093
|
+
const protocol = vpc["NetworkProtocol"];
|
|
11094
|
+
if (protocol !== void 0 && typeof protocol !== "string") fail("Configuration.VpcEgressConfiguration.NetworkProtocol must be a string");
|
|
11095
|
+
return {
|
|
11096
|
+
SubnetIds: subnetIds,
|
|
11097
|
+
SecurityGroupIds: securityGroupIds,
|
|
11098
|
+
NetworkProtocol: typeof protocol === "string" ? protocol : void 0,
|
|
11099
|
+
AssociatedComputeResourceTypes: types
|
|
11100
|
+
};
|
|
11101
|
+
}
|
|
11102
|
+
readOperatorRole(properties, logicalId, resourceType, physicalId, context) {
|
|
11103
|
+
const role = properties["OperatorRole"];
|
|
11104
|
+
if (role === void 0 || typeof role === "string") return role;
|
|
11105
|
+
const message = `OperatorRole must be a string for Lambda network connector ${logicalIdShown(logicalId)}`;
|
|
11106
|
+
if (context?.replayingState === true || context !== void 0 && "desiredFromAwsReadback" in context && context.desiredFromAwsReadback === true) {
|
|
11107
|
+
this.logger.warn(safeMsg`${message}; omitting it while applying a state-borne bag`);
|
|
11108
|
+
return;
|
|
11109
|
+
}
|
|
11110
|
+
throw new ProvisioningError(message, resourceType, logicalId, physicalId);
|
|
11111
|
+
}
|
|
11112
|
+
async reconcileTags(physicalId, resourceType, logicalId, newTags, oldTags) {
|
|
11113
|
+
const plan = planTagDiff(oldTags, newTags);
|
|
11114
|
+
const tagWarning = tagPlanWarning(plan, resourceType, logicalId);
|
|
11115
|
+
if (tagWarning !== void 0) this.logger.warn(tagWarning);
|
|
11116
|
+
if (plan.remove.length > 0) await this.lambda.send(new UntagResourceCommand$1({
|
|
11117
|
+
Resource: physicalId,
|
|
11118
|
+
TagKeys: plan.remove
|
|
11119
|
+
}));
|
|
11120
|
+
const toAdd = Object.fromEntries(plan.set);
|
|
11121
|
+
if (Object.keys(toAdd).length > 0) await this.lambda.send(new TagResourceCommand$1({
|
|
11122
|
+
Resource: physicalId,
|
|
11123
|
+
Tags: toAdd
|
|
11124
|
+
}));
|
|
11125
|
+
}
|
|
11126
|
+
async waitForSettled(arn, logicalId, operation) {
|
|
11127
|
+
for (let attempt = 1; attempt <= MAX_POLL_ATTEMPTS; attempt++) {
|
|
11128
|
+
const resp = await this.client.send(new GetNetworkConnectorCommand({ Identifier: arn }));
|
|
11129
|
+
if (resp.State === "FAILED" || resp.State === "DELETING" || resp.State === "DELETE_FAILED" || resp.State === "INACTIVE") throw new TerminalConnectorStateError(`Lambda network connector ${logicalIdShown(logicalId)} entered ${resp.State}: ${resp.StateReason ?? resp.StateReasonCode ?? "no reason given"}`);
|
|
11130
|
+
if (operation === "update" && resp.LastUpdateStatus === "Failed") throw new Error(`Lambda network connector ${logicalIdShown(logicalId)} update failed: ${resp.LastUpdateStatusReason ?? resp.LastUpdateStatusReasonCode ?? "no reason given"}`);
|
|
11131
|
+
if (resp.State === "ACTIVE" && resp.LastUpdateStatus !== "InProgress") return resp;
|
|
11132
|
+
await sleep$1(POLL_INTERVAL_MS$2);
|
|
11133
|
+
}
|
|
11134
|
+
throw new Error(`Lambda network connector ${logicalIdShown(logicalId)} did not finish ${operation} within ${MAX_POLL_ATTEMPTS * POLL_INTERVAL_MS$2 / 1e3}s.`);
|
|
11135
|
+
}
|
|
11136
|
+
async waitForGone(arn, logicalId) {
|
|
11137
|
+
for (let attempt = 1; attempt <= MAX_POLL_ATTEMPTS; attempt++) {
|
|
11138
|
+
let resp;
|
|
11139
|
+
try {
|
|
11140
|
+
resp = await this.client.send(new GetNetworkConnectorCommand({ Identifier: arn }));
|
|
11141
|
+
} catch (error) {
|
|
11142
|
+
if (error instanceof ResourceNotFoundException$10) return;
|
|
11143
|
+
throw error;
|
|
11144
|
+
}
|
|
11145
|
+
if (resp.State === "DELETE_FAILED") throw new Error(`Lambda network connector ${logicalIdShown(logicalId)} entered DELETE_FAILED: ${resp.StateReason ?? resp.StateReasonCode ?? "no reason given"}`);
|
|
11146
|
+
await sleep$1(POLL_INTERVAL_MS$2);
|
|
11147
|
+
}
|
|
11148
|
+
throw new Error(`Lambda network connector ${logicalIdShown(logicalId)} was not fully deleted within ${MAX_POLL_ATTEMPTS * POLL_INTERVAL_MS$2 / 1e3}s.`);
|
|
11149
|
+
}
|
|
11150
|
+
wrapError(operation, logicalId, resourceType, physicalId, error) {
|
|
11151
|
+
if (error instanceof ProvisioningError) return error;
|
|
11152
|
+
const cause = error instanceof Error ? error : void 0;
|
|
11153
|
+
return new ProvisioningError(`Failed to ${operation} Lambda network connector ${logicalIdShown(logicalId)}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
11154
|
+
}
|
|
11155
|
+
};
|
|
11156
|
+
var TerminalConnectorStateError = class extends Error {};
|
|
11157
|
+
function buildAttributes(resp) {
|
|
11158
|
+
return definedAttributes({
|
|
11159
|
+
Arn: resp.Arn,
|
|
11160
|
+
State: resp.State,
|
|
11161
|
+
LatestVersionArn: resp.LatestVersionArn,
|
|
11162
|
+
LatestVersion: resp.LatestVersion ?? versionOfArn(resp.LatestVersionArn)
|
|
11163
|
+
});
|
|
11164
|
+
}
|
|
11165
|
+
function versionOfArn(arn) {
|
|
11166
|
+
const match = arn === void 0 ? null : /:network-connector:[^:]+:(\d+)$/.exec(arn);
|
|
11167
|
+
return match ? Number(match[1]) : void 0;
|
|
11168
|
+
}
|
|
11169
|
+
|
|
10146
11170
|
//#endregion
|
|
10147
11171
|
//#region src/provisioning/dynamodb-contributor-insights.ts
|
|
10148
11172
|
const CONTRIBUTOR_INSIGHTS_KEY = "ContributorInsightsSpecification";
|
|
@@ -14105,6 +15129,7 @@ var EventBridgeRuleProvider = class {
|
|
|
14105
15129
|
this.logger.debug(`Deleting EventBridge rule ${logicalId}: ${physicalId}`);
|
|
14106
15130
|
const ruleName = this.extractRuleNameFromArn(physicalId);
|
|
14107
15131
|
const busParam = this.busParamFromArn(physicalId);
|
|
15132
|
+
let stripped = false;
|
|
14108
15133
|
try {
|
|
14109
15134
|
let targetIds = [];
|
|
14110
15135
|
try {
|
|
@@ -14127,6 +15152,7 @@ var EventBridgeRuleProvider = class {
|
|
|
14127
15152
|
Ids: targetIds,
|
|
14128
15153
|
...busParam
|
|
14129
15154
|
}));
|
|
15155
|
+
stripped = true;
|
|
14130
15156
|
this.logger.debug(`Removed ${targetIds.length} targets from rule ${ruleName}`);
|
|
14131
15157
|
}
|
|
14132
15158
|
await this.eventBridgeClient.send(new DeleteRuleCommand({
|
|
@@ -14142,7 +15168,8 @@ var EventBridgeRuleProvider = class {
|
|
|
14142
15168
|
return;
|
|
14143
15169
|
}
|
|
14144
15170
|
const cause = error instanceof Error ? error : void 0;
|
|
14145
|
-
|
|
15171
|
+
const failure = new ProvisioningError(`Failed to delete EventBridge rule ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
15172
|
+
throw stripped ? markDeleteStarted(failure) : failure;
|
|
14146
15173
|
}
|
|
14147
15174
|
}
|
|
14148
15175
|
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
@@ -14408,8 +15435,9 @@ var EventBridgeBusProvider = class {
|
|
|
14408
15435
|
}
|
|
14409
15436
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
14410
15437
|
this.logger.debug(`Deleting EventBus ${logicalId}: ${physicalId}`);
|
|
15438
|
+
let stripped = false;
|
|
14411
15439
|
try {
|
|
14412
|
-
await this.cleanupRulesOnBus(physicalId);
|
|
15440
|
+
stripped = await this.cleanupRulesOnBus(physicalId);
|
|
14413
15441
|
await this.eventBridgeClient.send(new DeleteEventBusCommand({ Name: physicalId }));
|
|
14414
15442
|
this.logger.debug(`Successfully deleted EventBus ${logicalId}`);
|
|
14415
15443
|
} catch (error) {
|
|
@@ -14427,7 +15455,8 @@ var EventBridgeBusProvider = class {
|
|
|
14427
15455
|
return;
|
|
14428
15456
|
}
|
|
14429
15457
|
const cause = error instanceof Error ? error : void 0;
|
|
14430
|
-
|
|
15458
|
+
const failure = new ProvisioningError(`Failed to delete EventBus ${logicalId}: ${msg}`, resourceType, logicalId, physicalId, cause);
|
|
15459
|
+
throw stripped ? markDeleteStarted(failure) : failure;
|
|
14431
15460
|
}
|
|
14432
15461
|
}
|
|
14433
15462
|
getAttribute(physicalId, _resourceType, attributeName) {
|
|
@@ -14436,9 +15465,11 @@ var EventBridgeBusProvider = class {
|
|
|
14436
15465
|
return Promise.resolve(void 0);
|
|
14437
15466
|
}
|
|
14438
15467
|
async cleanupRulesOnBus(busName) {
|
|
15468
|
+
let found = false;
|
|
14439
15469
|
try {
|
|
14440
15470
|
const rules = (await this.eventBridgeClient.send(new ListRulesCommand({ EventBusName: busName }))).Rules ?? [];
|
|
14441
|
-
if (rules.length === 0) return;
|
|
15471
|
+
if (rules.length === 0) return false;
|
|
15472
|
+
found = true;
|
|
14442
15473
|
this.logger.debug(`Cleaning up ${rules.length} rule(s) on bus ${busName}`);
|
|
14443
15474
|
for (const rule of rules) {
|
|
14444
15475
|
if (!rule.Name) continue;
|
|
@@ -14461,9 +15492,10 @@ var EventBridgeBusProvider = class {
|
|
|
14461
15492
|
} catch {}
|
|
14462
15493
|
}
|
|
14463
15494
|
} catch (error) {
|
|
14464
|
-
if (error instanceof ResourceNotFoundException$2) return;
|
|
15495
|
+
if (error instanceof ResourceNotFoundException$2) return found;
|
|
14465
15496
|
this.logger.debug(`Failed to list rules on bus ${busName}: ${describeAwsFailure(error).detail}`);
|
|
14466
15497
|
}
|
|
15498
|
+
return found;
|
|
14467
15499
|
}
|
|
14468
15500
|
async readCurrentState(physicalId, _logicalId, _resourceType) {
|
|
14469
15501
|
try {
|
|
@@ -15168,7 +16200,10 @@ var EC2Provider = class {
|
|
|
15168
16200
|
} catch (error) {
|
|
15169
16201
|
const cause = error instanceof Error ? error : void 0;
|
|
15170
16202
|
const thrown = new ProvisioningError(`Failed to create VPC ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
15171
|
-
if (leftBehindId !== void 0)
|
|
16203
|
+
if (leftBehindId !== void 0) {
|
|
16204
|
+
markCreatedBeforeFailure(thrown, logicalId, resourceType, leftBehindId);
|
|
16205
|
+
markNonRetryable(thrown);
|
|
16206
|
+
}
|
|
15172
16207
|
throw thrown;
|
|
15173
16208
|
}
|
|
15174
16209
|
}
|
|
@@ -15514,6 +16549,7 @@ var EC2Provider = class {
|
|
|
15514
16549
|
let publicIp;
|
|
15515
16550
|
let created = false;
|
|
15516
16551
|
let createdId;
|
|
16552
|
+
let allocatedId;
|
|
15517
16553
|
try {
|
|
15518
16554
|
const input = {
|
|
15519
16555
|
Domain: requireConfigString(properties["Domain"], "vpc", "AWS::EC2::EIP Domain", replayWarn(this.logger, context)),
|
|
@@ -15533,6 +16569,7 @@ var EC2Provider = class {
|
|
|
15533
16569
|
}
|
|
15534
16570
|
created = true;
|
|
15535
16571
|
allocationId = response.AllocationId;
|
|
16572
|
+
allocatedId = allocationId;
|
|
15536
16573
|
publicIp = response.PublicIp;
|
|
15537
16574
|
try {
|
|
15538
16575
|
createdId = this.eipPhysicalId(logicalId, publicIp, allocationId);
|
|
@@ -15557,9 +16594,31 @@ var EC2Provider = class {
|
|
|
15557
16594
|
this.logger.debug(`Successfully created EIP ${logicalId}: ${allocationId} (${publicIp})`);
|
|
15558
16595
|
} catch (error) {
|
|
15559
16596
|
if (created) markAuxiliaryFailure(error, logicalId);
|
|
16597
|
+
if (createdId !== void 0 && allocatedId !== void 0) try {
|
|
16598
|
+
const releaseId = allocatedId;
|
|
16599
|
+
const watch = startInterruptWatch(`EIP ${logicalId} release`);
|
|
16600
|
+
try {
|
|
16601
|
+
await withRetry(() => this.ec2Client.send(new ReleaseAddressCommand({ AllocationId: releaseId })), logicalId, {
|
|
16602
|
+
maxRetries: 4,
|
|
16603
|
+
initialDelayMs: 500,
|
|
16604
|
+
isRetryable: (_text, releaseError) => isThrottlingError(releaseError),
|
|
16605
|
+
isInterrupted: watch.isInterrupted,
|
|
16606
|
+
onInterrupted: watch.onInterrupted
|
|
16607
|
+
});
|
|
16608
|
+
} finally {
|
|
16609
|
+
watch.dispose();
|
|
16610
|
+
}
|
|
16611
|
+
createdId = void 0;
|
|
16612
|
+
this.logger.debug(safeMsg`Released partially-created EIP ${logicalId} (${allocatedId})`);
|
|
16613
|
+
} catch (cleanupError) {
|
|
16614
|
+
this.logger.warn(safeMsg`Failed to release partially-created EIP ${logicalId} (${allocatedId}): ${describeAwsFailure(cleanupError).detail}. Manual release may be required: ${pasteableAwsCommand(context?.maskSecrets)`aws ec2 release-address --allocation-id ${allocatedId}`.render()}`);
|
|
16615
|
+
}
|
|
15560
16616
|
const cause = error instanceof Error ? error : void 0;
|
|
15561
16617
|
const thrown = new ProvisioningError(`Failed to create EIP ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
15562
|
-
if (createdId !== void 0)
|
|
16618
|
+
if (createdId !== void 0) {
|
|
16619
|
+
markCreatedBeforeFailure(thrown, logicalId, resourceType, createdId);
|
|
16620
|
+
markNonRetryable(thrown);
|
|
16621
|
+
}
|
|
15563
16622
|
throw thrown;
|
|
15564
16623
|
}
|
|
15565
16624
|
return {
|
|
@@ -18475,12 +19534,15 @@ var ApiGatewayProvider = class ApiGatewayProvider {
|
|
|
18475
19534
|
log.debug(`PathPart changed from "${log.value(oldPathPart)}" to "${log.value(newPathPart)}", replacing resource`);
|
|
18476
19535
|
const createResult = await this.createResource(logicalId, resourceType, properties, log);
|
|
18477
19536
|
let orphanReason;
|
|
19537
|
+
let oldResourceSurvivor = "unconfirmed";
|
|
18478
19538
|
try {
|
|
18479
19539
|
if (redactedDeleteAddressFields({ RestApiId: previousProperties["RestApiId"] }).length > 0) {
|
|
18480
19540
|
orphanReason = `old API Gateway Resource ${physicalId} was not deleted: its recorded RestApiId is redacted`;
|
|
19541
|
+
oldResourceSurvivor = "kept";
|
|
18481
19542
|
log.warn(safeMsg`Old API Gateway Resource ${physicalId} was not deleted during replacement: its ` + "recorded RestApiId is redacted in state, which names no API. The old resource may be orphaned and require manual cleanup.");
|
|
18482
19543
|
} else await this.deleteResource(logicalId, physicalId, resourceType, previousProperties);
|
|
18483
19544
|
} catch (error) {
|
|
19545
|
+
oldResourceSurvivor = replacedDeleteFailureVerdict(error);
|
|
18484
19546
|
orphanReason = log.mask(`old API Gateway Resource ${physicalId} could not be deleted: ${safeStringify(error)}`);
|
|
18485
19547
|
log.warn(`Failed to delete old API Gateway Resource ${physicalId} during replacement: ${safeStringify(error)}. The old resource may be orphaned and require manual cleanup.`);
|
|
18486
19548
|
}
|
|
@@ -18492,7 +19554,8 @@ var ApiGatewayProvider = class ApiGatewayProvider {
|
|
|
18492
19554
|
return orphanReason !== void 0 ? {
|
|
18493
19555
|
...base,
|
|
18494
19556
|
outcome: "partial",
|
|
18495
|
-
reason: orphanReason
|
|
19557
|
+
reason: orphanReason,
|
|
19558
|
+
...oldResourceSurvivor === "kept" && { oldResourceSurvivor }
|
|
18496
19559
|
} : base;
|
|
18497
19560
|
}
|
|
18498
19561
|
return {
|
|
@@ -20802,8 +21865,9 @@ var CloudFrontOAIProvider = class {
|
|
|
20802
21865
|
throw new ProvisioningError(`Failed to create CloudFront OAI ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
20803
21866
|
}
|
|
20804
21867
|
}
|
|
20805
|
-
async update(logicalId, physicalId, resourceType, properties, _previousProperties) {
|
|
21868
|
+
async update(logicalId, physicalId, resourceType, properties, _previousProperties, context) {
|
|
20806
21869
|
this.logger.debug(`Updating CloudFront OAI ${logicalId}: ${physicalId}`);
|
|
21870
|
+
assertRegionMatch(context?.expectedRegion ? await this.cloudFrontClient.config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update", "global");
|
|
20807
21871
|
const config = properties["CloudFrontOriginAccessIdentityConfig"];
|
|
20808
21872
|
try {
|
|
20809
21873
|
const comment = readConfigString(config, "Comment", "", "AWS::CloudFront::CloudFrontOriginAccessIdentity CloudFrontOriginAccessIdentityConfig");
|
|
@@ -20946,8 +22010,9 @@ var CloudFrontOACProvider = class {
|
|
|
20946
22010
|
throw new ProvisioningError(`Failed to create CloudFront Origin Access Control ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
20947
22011
|
}
|
|
20948
22012
|
}
|
|
20949
|
-
async update(logicalId, physicalId, resourceType, properties, _previousProperties) {
|
|
22013
|
+
async update(logicalId, physicalId, resourceType, properties, _previousProperties, context) {
|
|
20950
22014
|
this.logger.debug(`Updating CloudFront Origin Access Control ${logicalId}: ${physicalId}`);
|
|
22015
|
+
assertRegionMatch(context?.expectedRegion ? await this.cloudFrontClient.config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update", "global");
|
|
20951
22016
|
try {
|
|
20952
22017
|
const etag = (await this.cloudFrontClient.send(new GetOriginAccessControlCommand({ Id: physicalId }))).ETag;
|
|
20953
22018
|
if (!etag) throw new Error("GetOriginAccessControl did not return ETag");
|
|
@@ -21185,8 +22250,9 @@ var CloudFrontDistributionProvider = class {
|
|
|
21185
22250
|
if (comment !== "") parts.push(`comment ${JSON.stringify(comment)}`);
|
|
21186
22251
|
return parts.length > 0 ? parts.join(" and ") : "its creation time (the orphan is the newest distribution in this account)";
|
|
21187
22252
|
}
|
|
21188
|
-
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
22253
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
21189
22254
|
this.logger.debug(`Updating CloudFront Distribution ${logicalId}: ${physicalId}`);
|
|
22255
|
+
assertRegionMatch(context?.expectedRegion ? await this.cloudFrontClient.config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update", "global");
|
|
21190
22256
|
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
21191
22257
|
try {
|
|
21192
22258
|
const getConfigResponse = await this.cloudFrontClient.send(new GetDistributionConfigCommand({ Id: physicalId }));
|
|
@@ -21223,6 +22289,7 @@ var CloudFrontDistributionProvider = class {
|
|
|
21223
22289
|
}
|
|
21224
22290
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
21225
22291
|
this.logger.debug(`Deleting CloudFront Distribution ${logicalId}: ${physicalId}`);
|
|
22292
|
+
let stripped = false;
|
|
21226
22293
|
try {
|
|
21227
22294
|
let etag;
|
|
21228
22295
|
let config;
|
|
@@ -21242,11 +22309,13 @@ var CloudFrontDistributionProvider = class {
|
|
|
21242
22309
|
if (config.Enabled) {
|
|
21243
22310
|
this.logger.debug(`Disabling CloudFront Distribution ${physicalId} before deletion`);
|
|
21244
22311
|
config.Enabled = false;
|
|
21245
|
-
|
|
22312
|
+
const updateResponse = await this.cloudFrontClient.send(new UpdateDistributionCommand({
|
|
21246
22313
|
Id: physicalId,
|
|
21247
22314
|
IfMatch: etag,
|
|
21248
22315
|
DistributionConfig: config
|
|
21249
|
-
}))
|
|
22316
|
+
}));
|
|
22317
|
+
stripped = true;
|
|
22318
|
+
etag = updateResponse.ETag;
|
|
21250
22319
|
if (!await this.waitForDistributionStable(physicalId, false)) this.logger.warn(`Distribution ${shownId(physicalId)} disable did not settle (Deployed + disabled) within the wait budget; attempting delete anyway. If it fails with DistributionNotDisabled, retry the destroy or raise the budget with --resource-timeout AWS::CloudFront::Distribution=${commandHole("duration")}.`);
|
|
21251
22320
|
etag = (await this.cloudFrontClient.send(new GetDistributionConfigCommand({ Id: physicalId }))).ETag;
|
|
21252
22321
|
} else {
|
|
@@ -21266,7 +22335,8 @@ var CloudFrontDistributionProvider = class {
|
|
|
21266
22335
|
return;
|
|
21267
22336
|
}
|
|
21268
22337
|
const cause = error instanceof Error ? error : void 0;
|
|
21269
|
-
|
|
22338
|
+
const failure = new ProvisioningError(`Failed to delete CloudFront Distribution ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
22339
|
+
throw stripped ? markDeleteStarted(failure) : failure;
|
|
21270
22340
|
}
|
|
21271
22341
|
}
|
|
21272
22342
|
async readCurrentState(physicalId, _logicalId, resourceType, _properties) {
|
|
@@ -23201,6 +24271,7 @@ var ECSProvider = class {
|
|
|
23201
24271
|
if (skip) return skip;
|
|
23202
24272
|
}
|
|
23203
24273
|
} else cluster = recordedCluster;
|
|
24274
|
+
let stripped = false;
|
|
23204
24275
|
try {
|
|
23205
24276
|
try {
|
|
23206
24277
|
await client.send(new UpdateServiceCommand({
|
|
@@ -23208,6 +24279,8 @@ var ECSProvider = class {
|
|
|
23208
24279
|
service: physicalId,
|
|
23209
24280
|
desiredCount: 0
|
|
23210
24281
|
}));
|
|
24282
|
+
const recordedCount = properties?.["DesiredCount"];
|
|
24283
|
+
stripped = !(recordedCount === 0 || recordedCount === "0");
|
|
23211
24284
|
this.logger.debug(`Scaled down ECS service ${physicalId} to 0`);
|
|
23212
24285
|
} catch (error) {
|
|
23213
24286
|
if (this.isServiceNotFoundException(error)) {
|
|
@@ -23232,7 +24305,8 @@ var ECSProvider = class {
|
|
|
23232
24305
|
return;
|
|
23233
24306
|
}
|
|
23234
24307
|
const cause = error instanceof Error ? error : void 0;
|
|
23235
|
-
|
|
24308
|
+
const failure = new ProvisioningError(`Failed to delete ECS service ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
24309
|
+
throw stripped ? markDeleteStarted(failure) : failure;
|
|
23236
24310
|
}
|
|
23237
24311
|
}
|
|
23238
24312
|
async getServiceAttribute(physicalId, attributeName) {
|
|
@@ -27505,9 +28579,10 @@ var Route53Provider = class {
|
|
|
27505
28579
|
}
|
|
27506
28580
|
async deleteHostedZone(logicalId, physicalId, resourceType, context) {
|
|
27507
28581
|
this.logger.debug(`Deleting Route 53 hosted zone ${logicalId}: ${physicalId}`);
|
|
28582
|
+
const progress = { stripped: false };
|
|
27508
28583
|
try {
|
|
27509
|
-
await this.deleteQueryLoggingConfigForZone(physicalId, logicalId);
|
|
27510
|
-
await this.ensureAcceleratedRecoveryDisabledForDelete(physicalId, logicalId);
|
|
28584
|
+
await this.deleteQueryLoggingConfigForZone(physicalId, logicalId, progress);
|
|
28585
|
+
await this.ensureAcceleratedRecoveryDisabledForDelete(physicalId, logicalId, progress);
|
|
27511
28586
|
await this.getClient().send(new DeleteHostedZoneCommand({ Id: physicalId }));
|
|
27512
28587
|
this.logger.debug(`Successfully deleted hosted zone ${logicalId}`);
|
|
27513
28588
|
} catch (error) {
|
|
@@ -27517,12 +28592,12 @@ var Route53Provider = class {
|
|
|
27517
28592
|
this.logger.debug(`Hosted zone ${physicalId} does not exist, skipping deletion`);
|
|
27518
28593
|
return;
|
|
27519
28594
|
}
|
|
27520
|
-
if (error instanceof ProvisioningError) throw error;
|
|
27521
28595
|
const cause = error instanceof Error ? error : void 0;
|
|
27522
|
-
|
|
28596
|
+
const failure = error instanceof ProvisioningError ? error : new ProvisioningError(`Failed to delete hosted zone ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
28597
|
+
throw progress.stripped ? markDeleteStarted(failure) : failure;
|
|
27523
28598
|
}
|
|
27524
28599
|
}
|
|
27525
|
-
async ensureAcceleratedRecoveryDisabledForDelete(physicalId, logicalId) {
|
|
28600
|
+
async ensureAcceleratedRecoveryDisabledForDelete(physicalId, logicalId, progress) {
|
|
27526
28601
|
const client = this.getClient();
|
|
27527
28602
|
const pollIntervalMs = Number.parseInt(process.env["CDKD_R53_ACCEL_RECOVERY_POLL_INTERVAL_MS"] ?? "15000", 10);
|
|
27528
28603
|
const timeoutMs = Number.parseInt(process.env["CDKD_R53_ACCEL_RECOVERY_POLL_TIMEOUT_MS"] ?? "600000", 10);
|
|
@@ -27565,6 +28640,7 @@ var Route53Provider = class {
|
|
|
27565
28640
|
HostedZoneId: physicalId,
|
|
27566
28641
|
EnableAcceleratedRecovery: false
|
|
27567
28642
|
}));
|
|
28643
|
+
progress.stripped = true;
|
|
27568
28644
|
} else if (current === "DISABLING" || current === "DISABLING_HOSTED_ZONE_LOCKED") this.logger.debug(`Hosted zone ${physicalId} AcceleratedRecovery is already ${current} (a disabling phase); waiting for settle`);
|
|
27569
28645
|
const settled = await waitFor(/* @__PURE__ */ new Set(["DISABLED"]), "DISABLED");
|
|
27570
28646
|
this.logger.debug(`Hosted zone ${physicalId} AcceleratedRecoveryStatus settled to ${settled ?? "undefined (zone gone)"}`);
|
|
@@ -27917,11 +28993,18 @@ var Route53Provider = class {
|
|
|
27917
28993
|
throw error;
|
|
27918
28994
|
}
|
|
27919
28995
|
}
|
|
27920
|
-
async deleteQueryLoggingConfigForZone(zoneId, logicalId) {
|
|
28996
|
+
async deleteQueryLoggingConfigForZone(zoneId, logicalId, progress) {
|
|
27921
28997
|
try {
|
|
27922
28998
|
const configs = (await this.getClient().send(new ListQueryLoggingConfigsCommand({ HostedZoneId: zoneId }))).QueryLoggingConfigs ?? [];
|
|
27923
28999
|
for (const config of configs) if (config.Id) {
|
|
27924
|
-
|
|
29000
|
+
const before = progress?.stripped;
|
|
29001
|
+
if (progress) progress.stripped = true;
|
|
29002
|
+
try {
|
|
29003
|
+
await this.getClient().send(new DeleteQueryLoggingConfigCommand({ Id: config.Id }));
|
|
29004
|
+
} catch (deleteError) {
|
|
29005
|
+
if (progress && before !== void 0 && isRefusedByName(deleteError)) progress.stripped = before;
|
|
29006
|
+
throw deleteError;
|
|
29007
|
+
}
|
|
27925
29008
|
this.logger.debug(`Deleted query logging config ${config.Id} for hosted zone ${logicalId}`);
|
|
27926
29009
|
}
|
|
27927
29010
|
} catch (error) {
|
|
@@ -28528,8 +29611,9 @@ var WAFv2WebACLProvider = class {
|
|
|
28528
29611
|
throw new ProvisioningError(`Failed to create WAFv2 WebACL ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
28529
29612
|
}
|
|
28530
29613
|
}
|
|
28531
|
-
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
29614
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
28532
29615
|
this.logger.debug(`Updating WAFv2 WebACL ${logicalId}: ${physicalId}`);
|
|
29616
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update");
|
|
28533
29617
|
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
28534
29618
|
this.warnOnSdkUnsupportedRuleKeys(logicalId, properties["Rules"]);
|
|
28535
29619
|
try {
|
|
@@ -28575,6 +29659,7 @@ var WAFv2WebACLProvider = class {
|
|
|
28575
29659
|
}
|
|
28576
29660
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
28577
29661
|
this.logger.debug(`Deleting WAFv2 WebACL ${logicalId}: ${physicalId}`);
|
|
29662
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-delete");
|
|
28578
29663
|
try {
|
|
28579
29664
|
const { id, name, scope } = parseWebACLArn(physicalId);
|
|
28580
29665
|
const lockToken = (await this.getClient().send(new GetWebACLCommand({
|
|
@@ -29101,7 +30186,10 @@ var CognitoUserPoolProvider = class {
|
|
|
29101
30186
|
}
|
|
29102
30187
|
const cause = error instanceof Error ? error : void 0;
|
|
29103
30188
|
const thrown = new ProvisioningError(`Failed to create Cognito User Pool ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, poolName, cause);
|
|
29104
|
-
if (poolLeftBehind && createdUserPoolId)
|
|
30189
|
+
if (poolLeftBehind && createdUserPoolId) {
|
|
30190
|
+
markCreatedBeforeFailure(thrown, logicalId, resourceType, createdUserPoolId);
|
|
30191
|
+
markNonRetryable(thrown);
|
|
30192
|
+
}
|
|
29105
30193
|
throw thrown;
|
|
29106
30194
|
}
|
|
29107
30195
|
}
|
|
@@ -29414,7 +30502,7 @@ var CognitoUserPoolProvider = class {
|
|
|
29414
30502
|
} catch (bareError) {
|
|
29415
30503
|
failure = bareError;
|
|
29416
30504
|
}
|
|
29417
|
-
if (readOn && !(failure instanceof ResourceNotFoundException$
|
|
30505
|
+
if (readOn && !(failure instanceof ResourceNotFoundException$11)) {
|
|
29418
30506
|
this.logger.debug(safeMsg`Writing DeletionProtection back on ${physicalId} failed: ${describeAwsFailure(failure).detail}`);
|
|
29419
30507
|
return "read-on-write-failed";
|
|
29420
30508
|
}
|
|
@@ -29471,7 +30559,7 @@ var CognitoUserPoolProvider = class {
|
|
|
29471
30559
|
return;
|
|
29472
30560
|
}
|
|
29473
30561
|
if (!observedPool) {
|
|
29474
|
-
if (observeError instanceof ResourceNotFoundException$
|
|
30562
|
+
if (observeError instanceof ResourceNotFoundException$11) return;
|
|
29475
30563
|
if (observeError !== void 0 && isTransientCognitoFailure(observeError)) {
|
|
29476
30564
|
transientReadError = observeError;
|
|
29477
30565
|
return;
|
|
@@ -29494,7 +30582,7 @@ var CognitoUserPoolProvider = class {
|
|
|
29494
30582
|
flip.deleteAccepted = true;
|
|
29495
30583
|
this.logger.debug(`Successfully deleted Cognito User Pool ${logicalId}`);
|
|
29496
30584
|
} catch (error) {
|
|
29497
|
-
if (error instanceof ResourceNotFoundException$
|
|
30585
|
+
if (error instanceof ResourceNotFoundException$11) {
|
|
29498
30586
|
const clientRegion = await this.getClient().config.region();
|
|
29499
30587
|
assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
29500
30588
|
this.logger.debug(`Cognito User Pool ${physicalId} does not exist, skipping deletion`);
|
|
@@ -29528,7 +30616,7 @@ var CognitoUserPoolProvider = class {
|
|
|
29528
30616
|
if (earlier) earlier.echoedSince = true;
|
|
29529
30617
|
return;
|
|
29530
30618
|
} catch (echoError) {
|
|
29531
|
-
if (echoError instanceof ResourceNotFoundException$
|
|
30619
|
+
if (echoError instanceof ResourceNotFoundException$11) throw echoError;
|
|
29532
30620
|
if (observedOn && isAmbiguousWriteFailure(echoError)) flip.flippedOffByThisRun = true;
|
|
29533
30621
|
if (isTransientCognitoFailure(echoError)) throw echoError;
|
|
29534
30622
|
if (!isRefusedEcho(echoError)) {
|
|
@@ -29541,7 +30629,7 @@ var CognitoUserPoolProvider = class {
|
|
|
29541
30629
|
DeletionProtection: "INACTIVE"
|
|
29542
30630
|
}));
|
|
29543
30631
|
} catch (bareError) {
|
|
29544
|
-
if (bareError instanceof ResourceNotFoundException$
|
|
30632
|
+
if (bareError instanceof ResourceNotFoundException$11) throw bareError;
|
|
29545
30633
|
if (isAmbiguousWriteFailure(bareError)) {
|
|
29546
30634
|
if (observedOn) flip.flippedOffByThisRun = true;
|
|
29547
30635
|
if (!this.preFlipPools.has(flip)) this.preFlipPools.set(flip, {
|
|
@@ -29583,7 +30671,7 @@ var CognitoUserPoolProvider = class {
|
|
|
29583
30671
|
try {
|
|
29584
30672
|
resp = await this.getClient().send(new DescribeUserPoolCommand({ UserPoolId: physicalId }));
|
|
29585
30673
|
} catch (err) {
|
|
29586
|
-
if (err instanceof ResourceNotFoundException$
|
|
30674
|
+
if (err instanceof ResourceNotFoundException$11) return RESOURCE_NOT_FOUND;
|
|
29587
30675
|
throw err;
|
|
29588
30676
|
}
|
|
29589
30677
|
const pool = resp.UserPool;
|
|
@@ -29652,7 +30740,7 @@ var CognitoUserPoolProvider = class {
|
|
|
29652
30740
|
attributes: await this.userPoolAttributes(input.knownPhysicalId, resp.UserPool?.Arn)
|
|
29653
30741
|
};
|
|
29654
30742
|
} catch (err) {
|
|
29655
|
-
if (err instanceof ResourceNotFoundException$
|
|
30743
|
+
if (err instanceof ResourceNotFoundException$11) return null;
|
|
29656
30744
|
throw err;
|
|
29657
30745
|
}
|
|
29658
30746
|
const desiredName = typeof input.properties?.["UserPoolName"] === "string" ? input.properties["UserPoolName"] : void 0;
|
|
@@ -29668,7 +30756,7 @@ var CognitoUserPoolProvider = class {
|
|
|
29668
30756
|
try {
|
|
29669
30757
|
resp = await this.getClient().send(new DescribeUserPoolCommand({ UserPoolId: pool.Id }));
|
|
29670
30758
|
} catch (err) {
|
|
29671
|
-
if (err instanceof ResourceNotFoundException$
|
|
30759
|
+
if (err instanceof ResourceNotFoundException$11) return null;
|
|
29672
30760
|
throw err;
|
|
29673
30761
|
}
|
|
29674
30762
|
return {
|
|
@@ -30178,6 +31266,13 @@ const NAMESPACE_TYPES = [
|
|
|
30178
31266
|
"AWS::ServiceDiscovery::HttpNamespace",
|
|
30179
31267
|
"AWS::ServiceDiscovery::PublicDnsNamespace"
|
|
30180
31268
|
];
|
|
31269
|
+
const NAMESPACE_KIND_BY_TYPE = /* @__PURE__ */ new Map([
|
|
31270
|
+
["AWS::ServiceDiscovery::PrivateDnsNamespace", "DNS_PRIVATE"],
|
|
31271
|
+
["AWS::ServiceDiscovery::PublicDnsNamespace", "DNS_PUBLIC"],
|
|
31272
|
+
["AWS::ServiceDiscovery::HttpNamespace", "HTTP"]
|
|
31273
|
+
]);
|
|
31274
|
+
const NAMESPACE_ID_PATTERN = /^ns-[a-z0-9]{16}$/;
|
|
31275
|
+
const SERVICE_ID_PATTERN = /^srv-[a-z0-9]{16}$/;
|
|
30181
31276
|
var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
|
|
30182
31277
|
client;
|
|
30183
31278
|
stsClient;
|
|
@@ -30783,6 +31878,47 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
|
|
|
30783
31878
|
default: return;
|
|
30784
31879
|
}
|
|
30785
31880
|
}
|
|
31881
|
+
async isSameResource(journaledPhysicalId, record, resourceType, context) {
|
|
31882
|
+
let pattern;
|
|
31883
|
+
let read;
|
|
31884
|
+
const namespaceKind = NAMESPACE_KIND_BY_TYPE.get(resourceType);
|
|
31885
|
+
if (namespaceKind !== void 0) {
|
|
31886
|
+
pattern = NAMESPACE_ID_PATTERN;
|
|
31887
|
+
read = (id) => this.readNamespaceIdForIdentity(id, namespaceKind);
|
|
31888
|
+
} else if (resourceType === "AWS::ServiceDiscovery::Service") {
|
|
31889
|
+
pattern = SERVICE_ID_PATTERN;
|
|
31890
|
+
read = (id) => this.readServiceIdForIdentity(id);
|
|
31891
|
+
} else return "unknown";
|
|
31892
|
+
if (!pattern.test(journaledPhysicalId) || !pattern.test(record.physicalId)) return "unknown";
|
|
31893
|
+
if (journaledPhysicalId === record.physicalId) return "same";
|
|
31894
|
+
if (await this.getClient().config.region() !== context.expectedRegion) return "unknown";
|
|
31895
|
+
if (await read(record.physicalId) !== record.physicalId) return "unknown";
|
|
31896
|
+
const journaledRead = await read(journaledPhysicalId);
|
|
31897
|
+
return journaledRead === void 0 || journaledRead === journaledPhysicalId ? "different" : "unknown";
|
|
31898
|
+
}
|
|
31899
|
+
async readNamespaceIdForIdentity(namespaceId, kind) {
|
|
31900
|
+
let response;
|
|
31901
|
+
try {
|
|
31902
|
+
response = await this.getClient().send(new GetNamespaceCommand({ Id: namespaceId }));
|
|
31903
|
+
} catch (error) {
|
|
31904
|
+
if (error instanceof NamespaceNotFound) return void 0;
|
|
31905
|
+
throw error;
|
|
31906
|
+
}
|
|
31907
|
+
const namespace = response.Namespace;
|
|
31908
|
+
if (typeof namespace?.Id !== "string" || namespace.Type !== kind) throw new Error("GetNamespace did not return a namespace of the kind asked for");
|
|
31909
|
+
return namespace.Id;
|
|
31910
|
+
}
|
|
31911
|
+
async readServiceIdForIdentity(serviceId) {
|
|
31912
|
+
let response;
|
|
31913
|
+
try {
|
|
31914
|
+
response = await this.getClient().send(new GetServiceCommand({ Id: serviceId }));
|
|
31915
|
+
} catch (error) {
|
|
31916
|
+
if (error instanceof ServiceNotFound) return void 0;
|
|
31917
|
+
throw error;
|
|
31918
|
+
}
|
|
31919
|
+
if (typeof response.Service?.Id !== "string") throw new Error("GetService did not return the service asked for");
|
|
31920
|
+
return response.Service.Id;
|
|
31921
|
+
}
|
|
30786
31922
|
async readCurrentState(physicalId, _logicalId, resourceType) {
|
|
30787
31923
|
switch (resourceType) {
|
|
30788
31924
|
case "AWS::ServiceDiscovery::PrivateDnsNamespace":
|
|
@@ -31908,7 +33044,10 @@ var AppSyncProvider = class {
|
|
|
31908
33044
|
}
|
|
31909
33045
|
const cause = error instanceof Error ? error : void 0;
|
|
31910
33046
|
const thrown = new ProvisioningError(`Failed to create GraphQL API ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
31911
|
-
if (apiLeftBehind && createdApiId)
|
|
33047
|
+
if (apiLeftBehind && createdApiId) {
|
|
33048
|
+
markCreatedBeforeFailure(thrown, logicalId, resourceType, createdApiId);
|
|
33049
|
+
markNonRetryable(thrown);
|
|
33050
|
+
}
|
|
31912
33051
|
throw thrown;
|
|
31913
33052
|
}
|
|
31914
33053
|
}
|
|
@@ -32817,6 +33956,7 @@ var GlueProvider = class {
|
|
|
32817
33956
|
}
|
|
32818
33957
|
}
|
|
32819
33958
|
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
33959
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-delete");
|
|
32820
33960
|
switch (resourceType) {
|
|
32821
33961
|
case "AWS::Glue::Database": return this.deleteDatabase(logicalId, physicalId, resourceType, properties, context);
|
|
32822
33962
|
case "AWS::Glue::Table": return this.deleteTable(logicalId, physicalId, resourceType, properties, context);
|
|
@@ -33522,6 +34662,7 @@ var GlueWorkflowProvider = class {
|
|
|
33522
34662
|
}
|
|
33523
34663
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
33524
34664
|
this.logger.debug(`Deleting Glue Workflow ${logicalId}: ${physicalId}`);
|
|
34665
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-delete");
|
|
33525
34666
|
try {
|
|
33526
34667
|
await this.getClient().send(new DeleteWorkflowCommand({ Name: physicalId }));
|
|
33527
34668
|
this.logger.debug(`Successfully deleted Glue Workflow ${logicalId}`);
|
|
@@ -33643,11 +34784,13 @@ var GlueSecurityConfigurationProvider = class {
|
|
|
33643
34784
|
throw this.wrapMaskedError(log.mask, error, (text) => new ProvisioningError(`Failed to create Glue SecurityConfiguration ${logicalId}: ${text}`, resourceType, logicalId, void 0, cause));
|
|
33644
34785
|
}
|
|
33645
34786
|
}
|
|
33646
|
-
async update(logicalId,
|
|
34787
|
+
async update(logicalId, physicalId, resourceType, _properties, _previousProperties, context) {
|
|
34788
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update");
|
|
33647
34789
|
throw new ResourceUpdateNotSupportedError(resourceType, logicalId, "AWS Glue SecurityConfiguration is immutable on AWS — there is no UpdateSecurityConfiguration API; every change requires DeleteSecurityConfiguration + CreateSecurityConfiguration. Use cdkd deploy --replace, or destroy + redeploy with the new EncryptionConfiguration.");
|
|
33648
34790
|
}
|
|
33649
34791
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
33650
34792
|
this.logger.debug(`Deleting Glue SecurityConfiguration ${logicalId}: ${physicalId}`);
|
|
34793
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-delete");
|
|
33651
34794
|
try {
|
|
33652
34795
|
await this.getClient().send(new DeleteSecurityConfigurationCommand({ Name: physicalId }));
|
|
33653
34796
|
this.logger.debug(`Successfully deleted Glue SecurityConfiguration ${logicalId}`);
|
|
@@ -33899,6 +35042,7 @@ var GlueJobProvider = class {
|
|
|
33899
35042
|
}
|
|
33900
35043
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
33901
35044
|
this.logger.debug(`Deleting Glue Job ${logicalId}: ${physicalId}`);
|
|
35045
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-delete");
|
|
33902
35046
|
try {
|
|
33903
35047
|
await this.getClient().send(new DeleteJobCommand({ JobName: physicalId }));
|
|
33904
35048
|
} catch (error) {
|
|
@@ -34190,6 +35334,7 @@ var GlueCrawlerProvider = class {
|
|
|
34190
35334
|
const log = createMaskedLogSinks(this.logger, context?.maskSecrets);
|
|
34191
35335
|
const { value: v } = log;
|
|
34192
35336
|
log.debug(`Deleting Glue Crawler ${logicalId}: ${v(physicalId)}`);
|
|
35337
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-delete");
|
|
34193
35338
|
try {
|
|
34194
35339
|
await this.getClient().send(new DeleteCrawlerCommand({ Name: physicalId }));
|
|
34195
35340
|
} catch (error) {
|
|
@@ -34437,6 +35582,7 @@ var GlueConnectionProvider = class {
|
|
|
34437
35582
|
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
34438
35583
|
const log = createMaskedLogSinks(this.logger, context?.maskSecrets);
|
|
34439
35584
|
log.debug(`Deleting Glue Connection ${logicalId}: ${log.value(physicalId)}`);
|
|
35585
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-delete");
|
|
34440
35586
|
const redactedSkip = redactedDeleteAddressSkip(this.logger, logicalId, resourceType, redactedDeleteAddressFields({ CatalogId: properties?.["CatalogId"] }));
|
|
34441
35587
|
if (redactedSkip) return redactedSkip;
|
|
34442
35588
|
const target = deleteCatalogId(properties);
|
|
@@ -34653,10 +35799,18 @@ var GlueTriggerProvider = class {
|
|
|
34653
35799
|
}
|
|
34654
35800
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
34655
35801
|
this.logger.debug(`Deleting Glue Trigger ${logicalId}: ${physicalId}`);
|
|
35802
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-delete");
|
|
35803
|
+
let stripped = false;
|
|
34656
35804
|
try {
|
|
34657
35805
|
try {
|
|
34658
35806
|
if ((await this.getClient().send(new GetTriggerCommand({ Name: physicalId }))).Trigger?.State === "ACTIVATED") {
|
|
34659
|
-
|
|
35807
|
+
stripped = true;
|
|
35808
|
+
try {
|
|
35809
|
+
await this.getClient().send(new StopTriggerCommand({ Name: physicalId }));
|
|
35810
|
+
} catch (stopError) {
|
|
35811
|
+
if (isRefusedByName(stopError)) stripped = false;
|
|
35812
|
+
throw stopError;
|
|
35813
|
+
}
|
|
34660
35814
|
await this.waitForTriggerDeactivated(physicalId);
|
|
34661
35815
|
}
|
|
34662
35816
|
} catch (err) {
|
|
@@ -34671,7 +35825,8 @@ var GlueTriggerProvider = class {
|
|
|
34671
35825
|
return;
|
|
34672
35826
|
}
|
|
34673
35827
|
const cause = error instanceof Error ? error : void 0;
|
|
34674
|
-
|
|
35828
|
+
const failure = new ProvisioningError(`Failed to delete Glue Trigger ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
35829
|
+
throw stripped ? markDeleteStarted(failure) : failure;
|
|
34675
35830
|
}
|
|
34676
35831
|
}
|
|
34677
35832
|
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
@@ -34726,6 +35881,7 @@ var GlueTriggerProvider = class {
|
|
|
34726
35881
|
const createKeyLatch = new AmbiguousCreateLatch("CreateKey");
|
|
34727
35882
|
const keysCreatedByThisProcess = new RecentIdSet();
|
|
34728
35883
|
const pendingKeys = /* @__PURE__ */ new Map();
|
|
35884
|
+
const supersededAttempts = /* @__PURE__ */ new Map();
|
|
34729
35885
|
const RESUMABLE_KEY_STATES = /* @__PURE__ */ new Set([
|
|
34730
35886
|
"Enabled",
|
|
34731
35887
|
"Disabled",
|
|
@@ -34820,11 +35976,12 @@ var KMSProvider = class {
|
|
|
34820
35976
|
enabled: properties["Enabled"] !== false
|
|
34821
35977
|
})).digest("hex");
|
|
34822
35978
|
let createdKeyId;
|
|
35979
|
+
let supersededPending = false;
|
|
34823
35980
|
try {
|
|
34824
35981
|
const resumed = await this.resumeKeyFromFailedAttempt(logicalId, attemptKey, inputDigest);
|
|
34825
35982
|
let keyId;
|
|
34826
35983
|
let keyArn;
|
|
34827
|
-
if (resumed) ({keyId, keyArn} = resumed);
|
|
35984
|
+
if (resumed && resumed !== "superseded") ({keyId, keyArn} = resumed);
|
|
34828
35985
|
else {
|
|
34829
35986
|
const orphanWindow = createKeyLatch.take(logicalId);
|
|
34830
35987
|
if (orphanWindow !== void 0) await this.reportPossibleOrphanKeys(logicalId, input, orphanWindow);
|
|
@@ -34845,6 +36002,9 @@ var KMSProvider = class {
|
|
|
34845
36002
|
heldAtMs: Date.now()
|
|
34846
36003
|
});
|
|
34847
36004
|
createdKeyId = keyId;
|
|
36005
|
+
const declinedAtMs = supersededAttempts.get(attemptKey);
|
|
36006
|
+
supersededAttempts.delete(attemptKey);
|
|
36007
|
+
supersededPending = declinedAtMs !== void 0 && Date.now() - declinedAtMs <= 18e5;
|
|
34848
36008
|
const replayWindow = replayedSendWindow(result, attemptStartMs);
|
|
34849
36009
|
if (replayWindow !== void 0) await this.reportPossibleOrphanKeys(logicalId, input, replayWindow);
|
|
34850
36010
|
}
|
|
@@ -34880,7 +36040,10 @@ var KMSProvider = class {
|
|
|
34880
36040
|
}
|
|
34881
36041
|
const cause = error instanceof Error ? error : void 0;
|
|
34882
36042
|
const thrown = new ProvisioningError(`Failed to create KMS Key ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
34883
|
-
if (createdKeyId !== void 0)
|
|
36043
|
+
if (createdKeyId !== void 0) {
|
|
36044
|
+
markCreatedBeforeFailure(thrown, logicalId, resourceType, createdKeyId);
|
|
36045
|
+
if (supersededPending) markSupersedesEarlierCreate(thrown);
|
|
36046
|
+
}
|
|
34884
36047
|
throw thrown;
|
|
34885
36048
|
}
|
|
34886
36049
|
}
|
|
@@ -34903,6 +36066,8 @@ var KMSProvider = class {
|
|
|
34903
36066
|
const deletion = aws`aws kms schedule-key-deletion --key-id ${pending.keyId}${region} --pending-window-in-days 7`.render();
|
|
34904
36067
|
const notReused = (reason) => {
|
|
34905
36068
|
this.logger.warn(safeMsg`KMS key ${pending.keyId} was created for ${logicalId} by an earlier attempt of this deploy, but ${reason}, so this attempt creates a new key and that one is not recorded in cdkd state. If it is unused, schedule its deletion with: ${deletion}`);
|
|
36069
|
+
setBounded(supersededAttempts, attemptKey, Date.now());
|
|
36070
|
+
return "superseded";
|
|
34906
36071
|
};
|
|
34907
36072
|
if (pending.inputDigest !== inputDigest) return notReused("this attempt was asked for a key with different inputs");
|
|
34908
36073
|
let metadata;
|
|
@@ -36118,7 +37283,7 @@ var KinesisStreamProvider = class {
|
|
|
36118
37283
|
EnforceConsumerDeletion: true
|
|
36119
37284
|
}));
|
|
36120
37285
|
} catch (error) {
|
|
36121
|
-
if (error instanceof ResourceNotFoundException$
|
|
37286
|
+
if (error instanceof ResourceNotFoundException$12) {
|
|
36122
37287
|
const clientRegion = await this.getClient().config.region();
|
|
36123
37288
|
assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
36124
37289
|
if (context?.failedCreateOrphan === true) this.logger.info(safeMsg` Kinesis stream ${physicalId} (${logicalId}), which a failed deploy created, is already gone; nothing to delete`);
|
|
@@ -36155,7 +37320,7 @@ var KinesisStreamProvider = class {
|
|
|
36155
37320
|
try {
|
|
36156
37321
|
response = await this.getClient().send(new DescribeStreamSummaryCommand({ StreamName: physicalId }));
|
|
36157
37322
|
} catch (error) {
|
|
36158
|
-
if (error instanceof ResourceNotFoundException$
|
|
37323
|
+
if (error instanceof ResourceNotFoundException$12) return RESOURCE_NOT_FOUND;
|
|
36159
37324
|
throw error;
|
|
36160
37325
|
}
|
|
36161
37326
|
const arn = response.StreamDescriptionSummary?.StreamARN;
|
|
@@ -36169,7 +37334,7 @@ var KinesisStreamProvider = class {
|
|
|
36169
37334
|
try {
|
|
36170
37335
|
response = await this.getClient().send(new DescribeStreamSummaryCommand({ StreamName: streamName }));
|
|
36171
37336
|
} catch (error) {
|
|
36172
|
-
if (error instanceof ResourceNotFoundException$
|
|
37337
|
+
if (error instanceof ResourceNotFoundException$12) return void 0;
|
|
36173
37338
|
throw error;
|
|
36174
37339
|
}
|
|
36175
37340
|
const arn = response.StreamDescriptionSummary?.StreamARN;
|
|
@@ -36180,7 +37345,7 @@ var KinesisStreamProvider = class {
|
|
|
36180
37345
|
try {
|
|
36181
37346
|
return (await this.getClient().send(new DescribeStreamSummaryCommand({ StreamName: streamName }))).StreamDescriptionSummary?.StreamStatus ?? "UNKNOWN";
|
|
36182
37347
|
} catch (error) {
|
|
36183
|
-
if (error instanceof ResourceNotFoundException$
|
|
37348
|
+
if (error instanceof ResourceNotFoundException$12) return void 0;
|
|
36184
37349
|
throw error;
|
|
36185
37350
|
}
|
|
36186
37351
|
}
|
|
@@ -36233,7 +37398,7 @@ var KinesisStreamProvider = class {
|
|
|
36233
37398
|
try {
|
|
36234
37399
|
stream = (await this.getClient().send(new DescribeStreamCommand({ StreamName: physicalId }))).StreamDescription;
|
|
36235
37400
|
} catch (err) {
|
|
36236
|
-
if (err instanceof ResourceNotFoundException$
|
|
37401
|
+
if (err instanceof ResourceNotFoundException$12) return RESOURCE_NOT_FOUND;
|
|
36237
37402
|
throw err;
|
|
36238
37403
|
}
|
|
36239
37404
|
if (!stream) return void 0;
|
|
@@ -36253,14 +37418,14 @@ var KinesisStreamProvider = class {
|
|
|
36253
37418
|
const maxRecordSize = (await this.getClient().send(new DescribeStreamSummaryCommand({ StreamName: physicalId }))).StreamDescriptionSummary?.MaxRecordSizeInKiB;
|
|
36254
37419
|
if (maxRecordSize !== void 0) result["MaxRecordSizeInKiB"] = maxRecordSize;
|
|
36255
37420
|
} catch (err) {
|
|
36256
|
-
if (err instanceof ResourceNotFoundException$
|
|
37421
|
+
if (err instanceof ResourceNotFoundException$12) return RESOURCE_NOT_FOUND;
|
|
36257
37422
|
throw err;
|
|
36258
37423
|
}
|
|
36259
37424
|
try {
|
|
36260
37425
|
const tagsResp = await this.getClient().send(new ListTagsForStreamCommand({ StreamName: physicalId }));
|
|
36261
37426
|
result["Tags"] = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
36262
37427
|
} catch (err) {
|
|
36263
|
-
if (err instanceof ResourceNotFoundException$
|
|
37428
|
+
if (err instanceof ResourceNotFoundException$12) return RESOURCE_NOT_FOUND;
|
|
36264
37429
|
this.logger.debug(`Kinesis ListTagsForStream(${physicalId}) failed: ${describeAwsFailure(err).detail}`);
|
|
36265
37430
|
}
|
|
36266
37431
|
return result;
|
|
@@ -36274,7 +37439,7 @@ var KinesisStreamProvider = class {
|
|
|
36274
37439
|
attributes: {}
|
|
36275
37440
|
};
|
|
36276
37441
|
} catch (err) {
|
|
36277
|
-
if (err instanceof ResourceNotFoundException$
|
|
37442
|
+
if (err instanceof ResourceNotFoundException$12) return null;
|
|
36278
37443
|
throw err;
|
|
36279
37444
|
}
|
|
36280
37445
|
return null;
|
|
@@ -36434,7 +37599,7 @@ var KinesisStreamConsumerProvider = class {
|
|
|
36434
37599
|
await this.getClient().send(new DeregisterStreamConsumerCommand({ ConsumerARN: physicalId }));
|
|
36435
37600
|
this.logger.debug(`Successfully deregistered Kinesis stream consumer ${logicalId}`);
|
|
36436
37601
|
} catch (error) {
|
|
36437
|
-
if (error instanceof ResourceNotFoundException$
|
|
37602
|
+
if (error instanceof ResourceNotFoundException$12) {
|
|
36438
37603
|
const clientRegion = await this.getClient().config.region();
|
|
36439
37604
|
assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
36440
37605
|
this.logger.debug(`Kinesis stream consumer ${physicalId} not found, skipping`);
|
|
@@ -36462,7 +37627,7 @@ var KinesisStreamConsumerProvider = class {
|
|
|
36462
37627
|
try {
|
|
36463
37628
|
desc = (await this.getClient().send(new DescribeStreamConsumerCommand({ ConsumerARN: physicalId }))).ConsumerDescription;
|
|
36464
37629
|
} catch (err) {
|
|
36465
|
-
if (err instanceof ResourceNotFoundException$
|
|
37630
|
+
if (err instanceof ResourceNotFoundException$12) return RESOURCE_NOT_FOUND;
|
|
36466
37631
|
throw err;
|
|
36467
37632
|
}
|
|
36468
37633
|
if (!desc) return void 0;
|
|
@@ -36473,7 +37638,7 @@ var KinesisStreamConsumerProvider = class {
|
|
|
36473
37638
|
const tagsResp = await this.getClient().send(new ListTagsForResourceCommand$15({ ResourceARN: physicalId }));
|
|
36474
37639
|
result["Tags"] = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
36475
37640
|
} catch (err) {
|
|
36476
|
-
if (err instanceof ResourceNotFoundException$
|
|
37641
|
+
if (err instanceof ResourceNotFoundException$12) return RESOURCE_NOT_FOUND;
|
|
36477
37642
|
this.logger.debug(`ListTagsForResource(${physicalId}) failed: ${describeAwsFailure(err).detail}`);
|
|
36478
37643
|
result["Tags"] = [];
|
|
36479
37644
|
}
|
|
@@ -36692,7 +37857,7 @@ var SchedulerScheduleProvider = class {
|
|
|
36692
37857
|
for (let attempt = 0;; attempt++) try {
|
|
36693
37858
|
return (await this.readIdentity(name, groupName)).creation;
|
|
36694
37859
|
} catch (error) {
|
|
36695
|
-
const transient = error instanceof ResourceNotFoundException$
|
|
37860
|
+
const transient = error instanceof ResourceNotFoundException$13 || isThrottlingError(error);
|
|
36696
37861
|
const delay = this.readBackDelaysMs[attempt];
|
|
36697
37862
|
if (transient && delay !== void 0) {
|
|
36698
37863
|
await this.sleep(delay);
|
|
@@ -36716,7 +37881,7 @@ var SchedulerScheduleProvider = class {
|
|
|
36716
37881
|
try {
|
|
36717
37882
|
live = await this.readIdentity(physicalId, groupName);
|
|
36718
37883
|
} catch (error) {
|
|
36719
|
-
if (error instanceof ResourceNotFoundException$
|
|
37884
|
+
if (error instanceof ResourceNotFoundException$13) return "absent";
|
|
36720
37885
|
throw this.wrapUnconfirmedGroupError(logicalId, physicalId, resourceType, error, mask);
|
|
36721
37886
|
}
|
|
36722
37887
|
if (sameRecordedDate(live, recorded) && !sameRecordedIdentity(live, recorded)) this.refuseUnconfirmed(logicalId, physicalId, resourceType, "holds a schedule of this name that carries the recorded creation date but not the recorded target or role (edited outside cdkd?)", false, "restore them, or drop the record with `cdkd orphan <construct path>` and deploy again");
|
|
@@ -36807,7 +37972,7 @@ var SchedulerScheduleProvider = class {
|
|
|
36807
37972
|
try {
|
|
36808
37973
|
live = await this.readIdentity(physicalId, group);
|
|
36809
37974
|
} catch (error) {
|
|
36810
|
-
if (error instanceof ResourceNotFoundException$
|
|
37975
|
+
if (error instanceof ResourceNotFoundException$13) continue;
|
|
36811
37976
|
throw wrapDeleteError("reading a schedule of its name", error);
|
|
36812
37977
|
}
|
|
36813
37978
|
if (sameRecordedIdentity(live, recorded)) matches.push(group);
|
|
@@ -36843,7 +38008,7 @@ var SchedulerScheduleProvider = class {
|
|
|
36843
38008
|
}));
|
|
36844
38009
|
this.logger.debug(safeMsg`Deleted Schedule ${logicalId} (found by its recorded creation date)`);
|
|
36845
38010
|
} catch (error) {
|
|
36846
|
-
if (error instanceof ResourceNotFoundException$
|
|
38011
|
+
if (error instanceof ResourceNotFoundException$13) return;
|
|
36847
38012
|
throw wrapDeleteError("the delete", error);
|
|
36848
38013
|
}
|
|
36849
38014
|
}
|
|
@@ -36873,7 +38038,7 @@ var SchedulerScheduleProvider = class {
|
|
|
36873
38038
|
}));
|
|
36874
38039
|
this.logger.debug(`Deleted Schedule ${logicalId}`);
|
|
36875
38040
|
} catch (error) {
|
|
36876
|
-
if (error instanceof ResourceNotFoundException$
|
|
38041
|
+
if (error instanceof ResourceNotFoundException$13) {
|
|
36877
38042
|
const clientRegion = await this.getClient().config.region();
|
|
36878
38043
|
assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
36879
38044
|
this.logger.debug(`Schedule ${logicalId} already deleted (not found), treating as success`);
|
|
@@ -36889,7 +38054,7 @@ var SchedulerScheduleProvider = class {
|
|
|
36889
38054
|
return (await this.getClient().send(new GetScheduleCommand({ Name: physicalId }))).Arn;
|
|
36890
38055
|
} catch (error) {
|
|
36891
38056
|
const cause = error instanceof Error ? error : void 0;
|
|
36892
|
-
const customGroupHint = error instanceof ResourceNotFoundException$
|
|
38057
|
+
const customGroupHint = error instanceof ResourceNotFoundException$13 ? " Schedules in a custom group cannot be looked up by bare name; the Arn is normally served from cdkd state attributes." : "";
|
|
36893
38058
|
throw new ProvisioningError(`Failed to resolve Arn for Schedule ${physicalId}: ${cause?.message ?? String(error)}.${customGroupHint}`, resourceType, logicalId, physicalId, cause);
|
|
36894
38059
|
}
|
|
36895
38060
|
}
|
|
@@ -36915,7 +38080,7 @@ var SchedulerScheduleProvider = class {
|
|
|
36915
38080
|
...response.Target !== void 0 && { Target: this.toCfnTarget(response.Target) }
|
|
36916
38081
|
};
|
|
36917
38082
|
} catch (error) {
|
|
36918
|
-
if (error instanceof ResourceNotFoundException$
|
|
38083
|
+
if (error instanceof ResourceNotFoundException$13) return RESOURCE_NOT_FOUND;
|
|
36919
38084
|
throw error;
|
|
36920
38085
|
}
|
|
36921
38086
|
}
|
|
@@ -36936,7 +38101,7 @@ var SchedulerScheduleProvider = class {
|
|
|
36936
38101
|
}
|
|
36937
38102
|
};
|
|
36938
38103
|
} catch (error) {
|
|
36939
|
-
if (error instanceof ResourceNotFoundException$
|
|
38104
|
+
if (error instanceof ResourceNotFoundException$13) return null;
|
|
36940
38105
|
throw error;
|
|
36941
38106
|
}
|
|
36942
38107
|
}
|
|
@@ -36945,6 +38110,32 @@ var SchedulerScheduleProvider = class {
|
|
|
36945
38110
|
//#endregion
|
|
36946
38111
|
//#region src/provisioning/providers/pipes-provider.ts
|
|
36947
38112
|
const PIPE_TYPE = "AWS::Pipes::Pipe";
|
|
38113
|
+
function isPipeName(id) {
|
|
38114
|
+
return /^[.\-_A-Za-z0-9]{1,64}$/.test(id);
|
|
38115
|
+
}
|
|
38116
|
+
const IDENTITY_STATES = /* @__PURE__ */ new Set([
|
|
38117
|
+
"CREATING",
|
|
38118
|
+
"CREATE_FAILED",
|
|
38119
|
+
"CREATE_ROLLBACK_FAILED",
|
|
38120
|
+
"RUNNING",
|
|
38121
|
+
"STARTING",
|
|
38122
|
+
"START_FAILED",
|
|
38123
|
+
"STOPPED",
|
|
38124
|
+
"STOPPING",
|
|
38125
|
+
"STOP_FAILED",
|
|
38126
|
+
"UPDATING",
|
|
38127
|
+
"UPDATE_FAILED",
|
|
38128
|
+
"UPDATE_ROLLBACK_FAILED",
|
|
38129
|
+
"DELETE_FAILED",
|
|
38130
|
+
"DELETE_ROLLBACK_FAILED"
|
|
38131
|
+
]);
|
|
38132
|
+
function pipeIdentityToken(name, arn, creationTime) {
|
|
38133
|
+
if (typeof arn !== "string" || !arn.startsWith("arn:") || !arn.endsWith(`:pipe/${name}`)) return;
|
|
38134
|
+
if (!(creationTime instanceof Date)) return void 0;
|
|
38135
|
+
const ms = creationTime.getTime();
|
|
38136
|
+
if (!Number.isFinite(ms) || ms <= 0) return void 0;
|
|
38137
|
+
return `${arn}@${Math.floor(ms / 1e3)}`;
|
|
38138
|
+
}
|
|
36948
38139
|
const SETTLED_STATES = /* @__PURE__ */ new Set(["RUNNING", "STOPPED"]);
|
|
36949
38140
|
const PIPE_POLL_INTERVAL_MS = 5e3;
|
|
36950
38141
|
const PIPE_SETTLE_MAX_WAIT_MS = 9e5;
|
|
@@ -37163,8 +38354,9 @@ var PipesPipeProvider = class {
|
|
|
37163
38354
|
const name = properties["Name"] ?? generateResourceName(logicalId, { maxLength: 64 });
|
|
37164
38355
|
const tags = desiredTagMap(properties["Tags"], logicalId);
|
|
37165
38356
|
this.logger.debug(mask(`Creating Pipe ${logicalId}: ${name}`));
|
|
38357
|
+
let createdIdentity;
|
|
37166
38358
|
try {
|
|
37167
|
-
await this.getCreateClient().send(new CreatePipeCommand({
|
|
38359
|
+
const created = await this.getCreateClient().send(new CreatePipeCommand({
|
|
37168
38360
|
Name: name,
|
|
37169
38361
|
RoleArn: properties["RoleArn"],
|
|
37170
38362
|
Source: properties["Source"],
|
|
@@ -37179,6 +38371,7 @@ var PipesPipeProvider = class {
|
|
|
37179
38371
|
...properties["KmsKeyIdentifier"] !== void 0 && { KmsKeyIdentifier: properties["KmsKeyIdentifier"] },
|
|
37180
38372
|
...Object.keys(tags).length > 0 && { Tags: tags }
|
|
37181
38373
|
}));
|
|
38374
|
+
createdIdentity = pipeIdentityToken(name, created?.Arn, created?.CreationTime);
|
|
37182
38375
|
} catch (error) {
|
|
37183
38376
|
const cause = error instanceof Error ? error : void 0;
|
|
37184
38377
|
throw new ProvisioningError(`Failed to create Pipe ${logicalId}: ${mask(cause?.message ?? String(error))}`, resourceType, logicalId, void 0, cause);
|
|
@@ -37187,7 +38380,7 @@ var PipesPipeProvider = class {
|
|
|
37187
38380
|
try {
|
|
37188
38381
|
settled = await this.waitForSettled(name, logicalId, resourceType, "create", mask);
|
|
37189
38382
|
} catch (error) {
|
|
37190
|
-
throw await this.retireFailedCreate(name, logicalId, resourceType, error, mask);
|
|
38383
|
+
throw await this.retireFailedCreate(name, logicalId, resourceType, error, mask, createdIdentity);
|
|
37191
38384
|
}
|
|
37192
38385
|
return {
|
|
37193
38386
|
physicalId: name,
|
|
@@ -37270,7 +38463,7 @@ var PipesPipeProvider = class {
|
|
|
37270
38463
|
} catch (error) {
|
|
37271
38464
|
if (error instanceof NotFoundException$6) {
|
|
37272
38465
|
assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
37273
|
-
this.
|
|
38466
|
+
this.logGoneOnDelete(logicalId, physicalId, context);
|
|
37274
38467
|
return;
|
|
37275
38468
|
}
|
|
37276
38469
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -37288,6 +38481,43 @@ var PipesPipeProvider = class {
|
|
|
37288
38481
|
now: this.now
|
|
37289
38482
|
});
|
|
37290
38483
|
}
|
|
38484
|
+
logGoneOnDelete(logicalId, physicalId, context) {
|
|
38485
|
+
if (context?.failedCreateOrphan === true) this.logger.info(safeMsg` Pipe ${physicalId} (${logicalId}), which a failed deploy created, is already gone; nothing to delete`);
|
|
38486
|
+
else this.logger.debug(safeMsg`Pipe ${logicalId} already deleted (not found), treating as success`);
|
|
38487
|
+
}
|
|
38488
|
+
async isSameResource(journaledPhysicalId, record, resourceType, context) {
|
|
38489
|
+
if (resourceType !== PIPE_TYPE) return "unknown";
|
|
38490
|
+
if (!isPipeName(journaledPhysicalId) || !isPipeName(record.physicalId)) return "unknown";
|
|
38491
|
+
if (journaledPhysicalId === record.physicalId) return "same";
|
|
38492
|
+
if (journaledPhysicalId.toLowerCase() === record.physicalId.toLowerCase()) return "unknown";
|
|
38493
|
+
if (await this.getClient().config.region() !== context.expectedRegion) return "unknown";
|
|
38494
|
+
const recordPipe = await this.describeIfExists(record.physicalId);
|
|
38495
|
+
if (recordPipe === void 0) return "unknown";
|
|
38496
|
+
const recordArn = recordPipe.Arn;
|
|
38497
|
+
if (typeof recordArn !== "string" || recordArn === "") return "unknown";
|
|
38498
|
+
const journaledPipe = await this.describeIfExists(journaledPhysicalId);
|
|
38499
|
+
if (journaledPipe === void 0) return "different";
|
|
38500
|
+
const journaledArn = journaledPipe.Arn;
|
|
38501
|
+
if (typeof journaledArn !== "string" || journaledArn === "") return "unknown";
|
|
38502
|
+
return journaledArn === recordArn ? "same" : "different";
|
|
38503
|
+
}
|
|
38504
|
+
async resourceIdentity(physicalId, resourceType, context) {
|
|
38505
|
+
if (resourceType !== PIPE_TYPE || !isPipeName(physicalId)) return void 0;
|
|
38506
|
+
if (await this.getClient().config.region() !== context.expectedRegion) return void 0;
|
|
38507
|
+
const pipe = await this.describeIfExists(physicalId);
|
|
38508
|
+
if (pipe === void 0) return RESOURCE_NOT_FOUND;
|
|
38509
|
+
if (pipe.Name !== physicalId) return void 0;
|
|
38510
|
+
if (pipe.CurrentState === void 0 || !IDENTITY_STATES.has(pipe.CurrentState)) return;
|
|
38511
|
+
return pipeIdentityToken(physicalId, pipe.Arn, pipe.CreationTime);
|
|
38512
|
+
}
|
|
38513
|
+
async describeIfExists(name) {
|
|
38514
|
+
try {
|
|
38515
|
+
return await this.describe(name);
|
|
38516
|
+
} catch (error) {
|
|
38517
|
+
if (error instanceof NotFoundException$6) return void 0;
|
|
38518
|
+
throw error;
|
|
38519
|
+
}
|
|
38520
|
+
}
|
|
37291
38521
|
async getAttribute(physicalId, _resourceType, attributeName, _logicalId) {
|
|
37292
38522
|
let response;
|
|
37293
38523
|
try {
|
|
@@ -37407,9 +38637,9 @@ var PipesPipeProvider = class {
|
|
|
37407
38637
|
watch.dispose();
|
|
37408
38638
|
}
|
|
37409
38639
|
}
|
|
37410
|
-
async retireFailedCreate(name, logicalId, resourceType, error, mask) {
|
|
38640
|
+
async retireFailedCreate(name, logicalId, resourceType, error, mask, createdIdentity) {
|
|
37411
38641
|
const original = error instanceof Error ? error : new Error(String(error));
|
|
37412
|
-
const leftBehind = () => markCreatedBeforeFailure(original, logicalId, resourceType, name);
|
|
38642
|
+
const leftBehind = () => markNonRetryable(markCreatedBeforeFailure(original, logicalId, resourceType, name, createdIdentity));
|
|
37413
38643
|
const orphaned = async (why) => {
|
|
37414
38644
|
const aws = pasteableAwsCommand(mask);
|
|
37415
38645
|
const command = aws`aws pipes delete-pipe --name ${name}${await orphanCommandRegionArg(this.getClient(), aws)}`;
|
|
@@ -39493,7 +40723,10 @@ var EMRClusterProvider = class {
|
|
|
39493
40723
|
this.logger.warn(`Failed to roll back partially-created EMR Cluster ${clusterId}: ${describeAwsFailure(cleanupError).detail} — terminate it manually to stop billing`);
|
|
39494
40724
|
}
|
|
39495
40725
|
if (error instanceof ProvisioningError) {
|
|
39496
|
-
if (survivorId !== void 0)
|
|
40726
|
+
if (survivorId !== void 0) {
|
|
40727
|
+
markCreatedBeforeFailure(error, logicalId, resourceType, survivorId);
|
|
40728
|
+
markNonRetryable(error);
|
|
40729
|
+
}
|
|
39497
40730
|
throw error;
|
|
39498
40731
|
}
|
|
39499
40732
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -39501,6 +40734,7 @@ var EMRClusterProvider = class {
|
|
|
39501
40734
|
if (survivorId !== void 0) {
|
|
39502
40735
|
const thrown = new ProvisioningError(message, resourceType, logicalId, void 0, cause);
|
|
39503
40736
|
markCreatedBeforeFailure(thrown, logicalId, resourceType, survivorId);
|
|
40737
|
+
markNonRetryable(thrown);
|
|
39504
40738
|
throw thrown;
|
|
39505
40739
|
}
|
|
39506
40740
|
throw new ProvisioningError(message, resourceType, logicalId, void 0, cause);
|
|
@@ -40169,7 +41403,27 @@ var EMRInstanceGroupConfigProvider = class {
|
|
|
40169
41403
|
};
|
|
40170
41404
|
} catch (error) {
|
|
40171
41405
|
const thrown = error instanceof ProvisioningError ? error : new ProvisioningError(`Failed to add EMR instance group ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, error instanceof Error ? error : void 0);
|
|
40172
|
-
|
|
41406
|
+
let leftBehindGroupId = createdGroupId;
|
|
41407
|
+
if (leftBehindGroupId && properties["InstanceRole"] === "TASK") {
|
|
41408
|
+
const log = createMaskedLogSinks(this.logger, context?.maskSecrets);
|
|
41409
|
+
try {
|
|
41410
|
+
await this.getClient().send(new ModifyInstanceGroupsCommand({
|
|
41411
|
+
ClusterId: jobFlowId,
|
|
41412
|
+
InstanceGroups: [{
|
|
41413
|
+
InstanceGroupId: leftBehindGroupId,
|
|
41414
|
+
InstanceCount: 0
|
|
41415
|
+
}]
|
|
41416
|
+
}));
|
|
41417
|
+
log.warn(safeMsg`Scaled partially-created EMR TASK instance group ${logicalId} (${leftBehindGroupId}) to 0; EMR has no delete API, so the empty group stays on cluster ${log.value(jobFlowId)} until it terminates`);
|
|
41418
|
+
leftBehindGroupId = void 0;
|
|
41419
|
+
} catch (cleanupError) {
|
|
41420
|
+
log.warn(safeMsg`Failed to scale partially-created EMR TASK instance group ${logicalId} (${leftBehindGroupId}) to 0: ${describeAwsFailure(cleanupError).detail} — its instances are released when the parent cluster terminates`);
|
|
41421
|
+
}
|
|
41422
|
+
}
|
|
41423
|
+
if (leftBehindGroupId) {
|
|
41424
|
+
markCreatedBeforeFailure(thrown, logicalId, resourceType, leftBehindGroupId);
|
|
41425
|
+
markNonRetryable(thrown);
|
|
41426
|
+
}
|
|
40173
41427
|
throw thrown;
|
|
40174
41428
|
}
|
|
40175
41429
|
}
|
|
@@ -40475,7 +41729,10 @@ var EMRInstanceFleetConfigProvider = class {
|
|
|
40475
41729
|
};
|
|
40476
41730
|
} catch (error) {
|
|
40477
41731
|
const thrown = error instanceof ProvisioningError ? error : new ProvisioningError(`Failed to add EMR instance fleet ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, error instanceof Error ? error : void 0);
|
|
40478
|
-
if (createdFleetId)
|
|
41732
|
+
if (createdFleetId) {
|
|
41733
|
+
markCreatedBeforeFailure(thrown, logicalId, resourceType, createdFleetId);
|
|
41734
|
+
markNonRetryable(thrown);
|
|
41735
|
+
}
|
|
40479
41736
|
throw thrown;
|
|
40480
41737
|
}
|
|
40481
41738
|
}
|
|
@@ -40999,7 +42256,7 @@ var FirehoseProvider = class {
|
|
|
40999
42256
|
try {
|
|
41000
42257
|
await this.getClient().send(new DeleteDeliveryStreamCommand({ DeliveryStreamName: physicalId }));
|
|
41001
42258
|
} catch (error) {
|
|
41002
|
-
if (error instanceof ResourceNotFoundException$
|
|
42259
|
+
if (error instanceof ResourceNotFoundException$14) {
|
|
41003
42260
|
const clientRegion = await this.getClient().config.region();
|
|
41004
42261
|
assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
41005
42262
|
this.logger.debug(`Firehose delivery stream ${physicalId} does not exist, skipping deletion`);
|
|
@@ -41023,7 +42280,7 @@ var FirehoseProvider = class {
|
|
|
41023
42280
|
try {
|
|
41024
42281
|
return (await this.getClient().send(new DescribeDeliveryStreamCommand({ DeliveryStreamName: streamName }))).DeliveryStreamDescription?.DeliveryStreamStatus ?? "UNKNOWN";
|
|
41025
42282
|
} catch (error) {
|
|
41026
|
-
if (error instanceof ResourceNotFoundException$
|
|
42283
|
+
if (error instanceof ResourceNotFoundException$14) return void 0;
|
|
41027
42284
|
throw error;
|
|
41028
42285
|
}
|
|
41029
42286
|
}
|
|
@@ -41355,7 +42612,7 @@ var FirehoseProvider = class {
|
|
|
41355
42612
|
try {
|
|
41356
42613
|
desc = (await this.getClient().send(new DescribeDeliveryStreamCommand({ DeliveryStreamName: physicalId }))).DeliveryStreamDescription;
|
|
41357
42614
|
} catch (err) {
|
|
41358
|
-
if (err instanceof ResourceNotFoundException$
|
|
42615
|
+
if (err instanceof ResourceNotFoundException$14) return RESOURCE_NOT_FOUND;
|
|
41359
42616
|
throw err;
|
|
41360
42617
|
}
|
|
41361
42618
|
if (!desc) return void 0;
|
|
@@ -41387,7 +42644,7 @@ var FirehoseProvider = class {
|
|
|
41387
42644
|
const tagsResp = await this.getClient().send(new ListTagsForDeliveryStreamCommand({ DeliveryStreamName: physicalId }));
|
|
41388
42645
|
result["Tags"] = normalizeAwsTagsToCfn(tagsResp.Tags);
|
|
41389
42646
|
} catch (err) {
|
|
41390
|
-
if (err instanceof ResourceNotFoundException$
|
|
42647
|
+
if (err instanceof ResourceNotFoundException$14) return RESOURCE_NOT_FOUND;
|
|
41391
42648
|
this.logger.debug(`Firehose ListTagsForDeliveryStream(${physicalId}) failed: ${describeAwsFailure(err).detail}`);
|
|
41392
42649
|
result["Tags"] = [];
|
|
41393
42650
|
}
|
|
@@ -41405,7 +42662,7 @@ var FirehoseProvider = class {
|
|
|
41405
42662
|
attributes: {}
|
|
41406
42663
|
};
|
|
41407
42664
|
} catch (err) {
|
|
41408
|
-
if (err instanceof ResourceNotFoundException$
|
|
42665
|
+
if (err instanceof ResourceNotFoundException$14) return null;
|
|
41409
42666
|
throw err;
|
|
41410
42667
|
}
|
|
41411
42668
|
return null;
|
|
@@ -41752,12 +43009,18 @@ var CloudTrailProvider = class {
|
|
|
41752
43009
|
throw new ProvisioningError(`Failed to update CloudTrail Trail ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
41753
43010
|
}
|
|
41754
43011
|
}
|
|
41755
|
-
async delete(logicalId, physicalId, resourceType,
|
|
43012
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
41756
43013
|
this.logger.debug(`Deleting CloudTrail Trail ${logicalId}: ${physicalId}`);
|
|
43014
|
+
const recordedIsLogging = properties?.["IsLogging"];
|
|
43015
|
+
const recordedStopped = recordedIsLogging === false || recordedIsLogging === "false";
|
|
43016
|
+
let stripped = false;
|
|
41757
43017
|
try {
|
|
41758
43018
|
try {
|
|
43019
|
+
stripped = !recordedStopped;
|
|
41759
43020
|
await this.getClient().send(new StopLoggingCommand({ Name: physicalId }));
|
|
41760
|
-
} catch {
|
|
43021
|
+
} catch (stopError) {
|
|
43022
|
+
if (isRefusedByName(stopError)) stripped = false;
|
|
43023
|
+
}
|
|
41761
43024
|
await this.getClient().send(new DeleteTrailCommand({ Name: physicalId }));
|
|
41762
43025
|
this.logger.debug(`Successfully deleted CloudTrail Trail ${logicalId}`);
|
|
41763
43026
|
} catch (error) {
|
|
@@ -41768,7 +43031,8 @@ var CloudTrailProvider = class {
|
|
|
41768
43031
|
return;
|
|
41769
43032
|
}
|
|
41770
43033
|
const cause = error instanceof Error ? error : void 0;
|
|
41771
|
-
|
|
43034
|
+
const failure = new ProvisioningError(`Failed to delete CloudTrail Trail ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
43035
|
+
throw stripped ? markDeleteStarted(failure) : failure;
|
|
41772
43036
|
}
|
|
41773
43037
|
}
|
|
41774
43038
|
getAttribute(_physicalId, _resourceType, attributeName) {
|
|
@@ -42122,7 +43386,7 @@ var CodeBuildProvider = class {
|
|
|
42122
43386
|
await this.getClient().send(new DeleteProjectCommand({ name: physicalId }));
|
|
42123
43387
|
this.logger.debug(`Successfully deleted CodeBuild Project ${logicalId}`);
|
|
42124
43388
|
} catch (error) {
|
|
42125
|
-
if (error instanceof ResourceNotFoundException$
|
|
43389
|
+
if (error instanceof ResourceNotFoundException$15) {
|
|
42126
43390
|
const clientRegion = await this.getClient().config.region();
|
|
42127
43391
|
assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
42128
43392
|
this.logger.debug(`CodeBuild Project ${physicalId} does not exist, skipping deletion`);
|
|
@@ -42140,7 +43404,7 @@ var CodeBuildProvider = class {
|
|
|
42140
43404
|
try {
|
|
42141
43405
|
project = (await this.getClient().send(new BatchGetProjectsCommand({ names: [physicalId] }))).projects?.[0];
|
|
42142
43406
|
} catch (err) {
|
|
42143
|
-
if (err instanceof ResourceNotFoundException$
|
|
43407
|
+
if (err instanceof ResourceNotFoundException$15) return RESOURCE_NOT_FOUND;
|
|
42144
43408
|
throw err;
|
|
42145
43409
|
}
|
|
42146
43410
|
if (!project) return RESOURCE_NOT_FOUND;
|
|
@@ -42316,7 +43580,7 @@ var CodeBuildProvider = class {
|
|
|
42316
43580
|
attributes: {}
|
|
42317
43581
|
} : null;
|
|
42318
43582
|
} catch (err) {
|
|
42319
|
-
if (err instanceof ResourceNotFoundException$
|
|
43583
|
+
if (err instanceof ResourceNotFoundException$15) return null;
|
|
42320
43584
|
throw err;
|
|
42321
43585
|
}
|
|
42322
43586
|
return null;
|
|
@@ -42901,7 +44165,7 @@ var DLMLifecyclePolicyProvider = class {
|
|
|
42901
44165
|
created = detail.Policy?.DateCreated;
|
|
42902
44166
|
defaultType = detail.Policy?.PolicyDetails?.ResourceType;
|
|
42903
44167
|
} catch (error) {
|
|
42904
|
-
if (error instanceof ResourceNotFoundException$
|
|
44168
|
+
if (error instanceof ResourceNotFoundException$16) continue;
|
|
42905
44169
|
throw error;
|
|
42906
44170
|
}
|
|
42907
44171
|
if (isDefault && defaultType !== void 0 && defaultType !== input.DefaultPolicy) continue;
|
|
@@ -43050,7 +44314,7 @@ var DLMLifecyclePolicyProvider = class {
|
|
|
43050
44314
|
await this.getClient().send(new DeleteLifecyclePolicyCommand$1({ PolicyId: physicalId }));
|
|
43051
44315
|
this.logger.debug(`Successfully deleted DLM Lifecycle Policy ${logicalId}`);
|
|
43052
44316
|
} catch (error) {
|
|
43053
|
-
if (error instanceof ResourceNotFoundException$
|
|
44317
|
+
if (error instanceof ResourceNotFoundException$16) {
|
|
43054
44318
|
const clientRegion = await this.getClient().config.region();
|
|
43055
44319
|
assertRegionMatch(clientRegion, context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
43056
44320
|
this.logger.debug(`DLM Lifecycle Policy ${physicalId} does not exist, skipping deletion`);
|
|
@@ -43081,7 +44345,7 @@ var DLMLifecyclePolicyProvider = class {
|
|
|
43081
44345
|
Tags: normalizeAwsTagsToCfn(policy.Tags)
|
|
43082
44346
|
};
|
|
43083
44347
|
} catch (error) {
|
|
43084
|
-
if (error instanceof ResourceNotFoundException$
|
|
44348
|
+
if (error instanceof ResourceNotFoundException$16) return RESOURCE_NOT_FOUND;
|
|
43085
44349
|
throw error;
|
|
43086
44350
|
}
|
|
43087
44351
|
}
|
|
@@ -43105,7 +44369,7 @@ var DLMLifecyclePolicyProvider = class {
|
|
|
43105
44369
|
attributes: response.Policy.PolicyArn ? { Arn: response.Policy.PolicyArn } : {}
|
|
43106
44370
|
} : null;
|
|
43107
44371
|
} catch (err) {
|
|
43108
|
-
if (err instanceof ResourceNotFoundException$
|
|
44372
|
+
if (err instanceof ResourceNotFoundException$16) return null;
|
|
43109
44373
|
throw err;
|
|
43110
44374
|
}
|
|
43111
44375
|
return null;
|
|
@@ -43453,7 +44717,8 @@ var S3DirectoryBucketProvider = class {
|
|
|
43453
44717
|
throw new ProvisioningError(`Failed to create S3 Express Directory Bucket ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, bucketName, cause);
|
|
43454
44718
|
}
|
|
43455
44719
|
}
|
|
43456
|
-
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
44720
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
44721
|
+
if (context?.expectedRegion) for (const clientRegion of [await this.s3Client.config.region(), await this.getS3ControlClient().config.region()]) assertRegionMatch(clientRegion, context.expectedRegion, resourceType, logicalId, physicalId, "pre-update");
|
|
43457
44722
|
refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
43458
44723
|
try {
|
|
43459
44724
|
const plan = planTagDiff(previousProperties["Tags"], properties["Tags"]);
|
|
@@ -43491,6 +44756,7 @@ var S3DirectoryBucketProvider = class {
|
|
|
43491
44756
|
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
43492
44757
|
const mask = maskerOrIdentity(context?.maskSecrets);
|
|
43493
44758
|
this.logger.debug(mask(`Deleting S3 Express Directory Bucket ${logicalId}: ${mask(physicalId)}`));
|
|
44759
|
+
assertRegionMatch(context?.expectedRegion ? await this.s3Client.config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-delete");
|
|
43494
44760
|
const allowAutoEmpty = context?.forceDataDelete === true || hasCdkAutoDeleteTag(properties, "aws-cdk:auto-delete-objects");
|
|
43495
44761
|
try {
|
|
43496
44762
|
await this.deleteBucketWithEmptyRetry(logicalId, physicalId, allowAutoEmpty, context?.maskSecrets);
|
|
@@ -43682,7 +44948,8 @@ var S3TablesProvider = class {
|
|
|
43682
44948
|
default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
|
|
43683
44949
|
}
|
|
43684
44950
|
}
|
|
43685
|
-
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
44951
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
|
|
44952
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-update");
|
|
43686
44953
|
if (resourceType === "AWS::S3Tables::Table" || resourceType === "AWS::S3Tables::TableBucket") refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
|
|
43687
44954
|
try {
|
|
43688
44955
|
return await this.applyUpdate(logicalId, physicalId, resourceType, properties, previousProperties);
|
|
@@ -43702,6 +44969,7 @@ var S3TablesProvider = class {
|
|
|
43702
44969
|
};
|
|
43703
44970
|
}
|
|
43704
44971
|
async delete(logicalId, physicalId, resourceType, _properties, context) {
|
|
44972
|
+
assertRegionMatch(context?.expectedRegion ? await this.getClient().config.region() : void 0, context?.expectedRegion, resourceType, logicalId, physicalId, "pre-delete");
|
|
43705
44973
|
switch (resourceType) {
|
|
43706
44974
|
case "AWS::S3Tables::TableBucket": return this.deleteTableBucket(logicalId, physicalId, resourceType, context);
|
|
43707
44975
|
case "AWS::S3Tables::Namespace": return this.deleteNamespace(logicalId, physicalId, resourceType, context);
|
|
@@ -44979,12 +46247,16 @@ var WaitConditionHandleProvider = class {
|
|
|
44979
46247
|
|
|
44980
46248
|
//#endregion
|
|
44981
46249
|
//#region src/provisioning/providers/acm-certificate-provider.ts
|
|
44982
|
-
function
|
|
46250
|
+
function certificateInUseByName(error) {
|
|
44983
46251
|
let current = error;
|
|
44984
46252
|
for (let depth = 0; depth < 5 && current instanceof Error; depth++) {
|
|
44985
46253
|
if (current.name === "ResourceInUseException") return true;
|
|
44986
46254
|
current = current.cause;
|
|
44987
46255
|
}
|
|
46256
|
+
return false;
|
|
46257
|
+
}
|
|
46258
|
+
function isCertificateInUseError(error) {
|
|
46259
|
+
if (certificateInUseByName(error)) return true;
|
|
44988
46260
|
const message = error instanceof Error ? error.message : String(error);
|
|
44989
46261
|
return /ResourceInUseException|in use/i.test(message);
|
|
44990
46262
|
}
|
|
@@ -45131,6 +46403,7 @@ var ACMCertificateProvider = class {
|
|
|
45131
46403
|
this.logger.debug(`${changedImmutable} changed, replacing ACM certificate: ${physicalId}`);
|
|
45132
46404
|
const createResult = await this.create(logicalId, resourceType, properties);
|
|
45133
46405
|
let orphanReason;
|
|
46406
|
+
let oldResourceSurvivor = "unconfirmed";
|
|
45134
46407
|
try {
|
|
45135
46408
|
const deleteResult = await this.delete(logicalId, physicalId, resourceType, previousProperties, context?.maskSecrets ? { maskSecrets: context.maskSecrets } : void 0);
|
|
45136
46409
|
if (deleteResult?.outcome === "skipped") {
|
|
@@ -45139,6 +46412,7 @@ var ACMCertificateProvider = class {
|
|
|
45139
46412
|
}
|
|
45140
46413
|
} catch (error) {
|
|
45141
46414
|
const inUse = isCertificateInUseError(error);
|
|
46415
|
+
oldResourceSurvivor = certificateInUseByName(error) ? "kept" : replacedDeleteFailureVerdict(error);
|
|
45142
46416
|
orphanReason = inUse ? `old certificate ${physicalId} is still in use by another resource and was not deleted` : `old certificate ${physicalId} could not be deleted: ${safeStringify(error)}`;
|
|
45143
46417
|
this.logger.warn(`Failed to delete old ACM certificate ${physicalId} during replacement: ${safeStringify(error)}. ` + (inUse ? "This usually means a consumer (e.g. a CloudFront distribution) still references it; it can be deleted once DescribeCertificate.InUseBy is empty. " : "") + `The old certificate may be orphaned and require manual cleanup.`);
|
|
45144
46418
|
}
|
|
@@ -45150,7 +46424,8 @@ var ACMCertificateProvider = class {
|
|
|
45150
46424
|
return orphanReason !== void 0 ? {
|
|
45151
46425
|
...base,
|
|
45152
46426
|
outcome: "partial",
|
|
45153
|
-
reason: orphanReason
|
|
46427
|
+
reason: orphanReason,
|
|
46428
|
+
...oldResourceSurvivor === "kept" && { oldResourceSurvivor }
|
|
45154
46429
|
} : base;
|
|
45155
46430
|
}
|
|
45156
46431
|
try {
|
|
@@ -45316,5 +46591,5 @@ var ACMCertificateProvider = class {
|
|
|
45316
46591
|
};
|
|
45317
46592
|
|
|
45318
46593
|
//#endregion
|
|
45319
|
-
export { ACMCertificateProvider, ASGProvider, AgentCoreBrowserProvider, AgentCoreCodeInterpreterProvider, AgentCoreEvaluatorProvider, AgentCoreRuntimeProvider, ApiGatewayProvider, ApiGatewayV2Provider, AppSyncProvider, BudgetsBudgetProvider, CloudFrontDistributionProvider, CloudFrontOACProvider, CloudFrontOAIProvider, CloudTrailProvider, CloudWatchAlarmProvider, CloudWatchAnomalyDetectorProvider, CodeBuildProvider, CodeCommitRepositoryProvider, CognitoUserPoolProvider, DLMLifecyclePolicyProvider, DocDBProvider, DocDBSubnetGroupProvider, DynamoDBGlobalTableProvider, DynamoDBTableProvider, EC2Provider, ECRProvider, ECSProvider, EFSProvider, ELBv2Provider, EMRClusterProvider, EMRInstanceFleetConfigProvider, EMRInstanceGroupConfigProvider, ElastiCacheProvider, EventBridgeBusProvider, EventBridgeRuleProvider, FSxFileSystemProvider, FirehoseProvider, GlueConnectionProvider, GlueCrawlerProvider, GlueJobProvider, GlueProvider, GlueSecurityConfigurationProvider, GlueTriggerProvider, GlueWorkflowProvider, IAMAccessKeyProvider, IAMInstanceProfileProvider, IAMManagedPolicyProvider, IAMPolicyProvider, IAMRoleProvider, IAMUserGroupProvider, KMSProvider, KinesisStreamConsumerProvider, KinesisStreamProvider, LambdaEventInvokeConfigProvider, LambdaEventSourceMappingProvider, LambdaFunctionProvider, LambdaLayerVersionProvider, LambdaMicrovmImageProvider, LambdaPermissionProvider, LambdaUrlProvider, LogsLogGroupProvider, NeptuneProvider, NestedStackProvider, PipesPipeProvider, RDSDBProxyEndpointProvider, RDSDBProxyProvider, RDSDBProxyTargetGroupProvider, RDSProvider, Route53Provider, S3BucketPolicyProvider, S3BucketProvider, S3DirectoryBucketProvider, S3TablesProvider, S3VectorsProvider, SNSSubscriptionProvider, SNSTopicPolicyProvider, SNSTopicProvider, SQSQueuePolicyProvider, SQSQueueProvider, SSMParameterProvider, SchedulerScheduleProvider, SecretsManagerSecretProvider, ServiceDiscoveryProvider, StepFunctionsProvider, WAFv2WebACLProvider, WaitConditionHandleProvider };
|
|
45320
|
-
//# sourceMappingURL=provider-classes-
|
|
46594
|
+
export { ACMCertificateProvider, ASGProvider, AgentCoreBrowserProvider, AgentCoreCodeInterpreterProvider, AgentCoreEvaluatorProvider, AgentCoreRuntimeProvider, ApiGatewayProvider, ApiGatewayV2Provider, AppSyncProvider, BudgetsBudgetProvider, CloudFrontDistributionProvider, CloudFrontOACProvider, CloudFrontOAIProvider, CloudTrailProvider, CloudWatchAlarmProvider, CloudWatchAnomalyDetectorProvider, CodeBuildProvider, CodeCommitRepositoryProvider, CognitoUserPoolProvider, DLMLifecyclePolicyProvider, DocDBProvider, DocDBSubnetGroupProvider, DynamoDBGlobalTableProvider, DynamoDBTableProvider, EC2Provider, ECRProvider, ECSProvider, EFSProvider, ELBv2Provider, EMRClusterProvider, EMRInstanceFleetConfigProvider, EMRInstanceGroupConfigProvider, ElastiCacheProvider, EventBridgeBusProvider, EventBridgeRuleProvider, FSxFileSystemProvider, FirehoseProvider, GlueConnectionProvider, GlueCrawlerProvider, GlueJobProvider, GlueProvider, GlueSecurityConfigurationProvider, GlueTriggerProvider, GlueWorkflowProvider, IAMAccessKeyProvider, IAMInstanceProfileProvider, IAMManagedPolicyProvider, IAMPolicyProvider, IAMRoleProvider, IAMUserGroupProvider, KMSProvider, KinesisStreamConsumerProvider, KinesisStreamProvider, LambdaEventInvokeConfigProvider, LambdaEventSourceMappingProvider, LambdaFunctionProvider, LambdaLayerVersionProvider, LambdaMicrovmImageProvider, LambdaNetworkConnectorProvider, LambdaPermissionProvider, LambdaUrlProvider, LambdaWebFunctionEndpointProvider, LambdaWebFunctionRevisionProvider, LogsLogGroupProvider, NeptuneProvider, NestedStackProvider, PipesPipeProvider, RDSDBProxyEndpointProvider, RDSDBProxyProvider, RDSDBProxyTargetGroupProvider, RDSProvider, Route53Provider, S3BucketPolicyProvider, S3BucketProvider, S3DirectoryBucketProvider, S3TablesProvider, S3VectorsProvider, SNSSubscriptionProvider, SNSTopicPolicyProvider, SNSTopicProvider, SQSQueuePolicyProvider, SQSQueueProvider, SSMParameterProvider, SchedulerScheduleProvider, SecretsManagerSecretProvider, ServiceDiscoveryProvider, StepFunctionsProvider, WAFv2WebACLProvider, WaitConditionHandleProvider };
|
|
46595
|
+
//# sourceMappingURL=provider-classes-CDzT2xg0.js.map
|