@go-to-k/cdkd 0.102.1 → 0.102.3
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/cli.js +142 -81
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3435,15 +3435,27 @@ var S3BucketProvider = class {
|
|
|
3435
3435
|
const region = await this.getRegion();
|
|
3436
3436
|
if (region !== "us-east-1") createParams.CreateBucketConfiguration = { LocationConstraint: region };
|
|
3437
3437
|
if (properties["ObjectLockEnabled"] === true || properties["ObjectLockEnabled"] === "true") createParams.ObjectLockEnabledForBucket = true;
|
|
3438
|
+
let createdNewBucket = false;
|
|
3438
3439
|
try {
|
|
3439
3440
|
await this.s3Client.send(new CreateBucketCommand(createParams));
|
|
3441
|
+
createdNewBucket = true;
|
|
3440
3442
|
this.logger.debug(`Created S3 bucket: ${bucketName}`);
|
|
3441
3443
|
} catch (createError) {
|
|
3442
3444
|
if (createError instanceof Error && (createError.name === "BucketAlreadyOwnedByYou" || createError.message.includes("you already own it"))) this.logger.debug(`S3 bucket ${bucketName} already exists and is owned by you`);
|
|
3443
3445
|
else throw createError;
|
|
3444
3446
|
}
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
+
try {
|
|
3448
|
+
await this.applyConfiguration(bucketName, properties);
|
|
3449
|
+
await this.applyAllSubConfigsForCreate(bucketName, properties);
|
|
3450
|
+
} catch (innerError) {
|
|
3451
|
+
if (createdNewBucket) try {
|
|
3452
|
+
await this.s3Client.send(new DeleteBucketCommand({ Bucket: bucketName }));
|
|
3453
|
+
this.logger.debug(`Cleaned up partially-created S3 bucket ${logicalId} (${bucketName}) after wiring failure`);
|
|
3454
|
+
} catch (cleanupError) {
|
|
3455
|
+
this.logger.warn(`Failed to clean up partially-created S3 bucket ${logicalId} (${bucketName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws s3api delete-bucket --bucket '${bucketName}'`);
|
|
3456
|
+
}
|
|
3457
|
+
throw innerError;
|
|
3458
|
+
}
|
|
3447
3459
|
const attributes = await this.buildAttributes(bucketName);
|
|
3448
3460
|
this.logger.debug(`Successfully created S3 bucket ${logicalId}: ${bucketName}`);
|
|
3449
3461
|
return {
|
|
@@ -7810,46 +7822,56 @@ var LogsLogGroupProvider = class {
|
|
|
7810
7822
|
const cfnTags = properties["Tags"];
|
|
7811
7823
|
createParams.tags = Object.fromEntries(cfnTags.map((t) => [t.Key, t.Value]));
|
|
7812
7824
|
}
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
const policyDocument = typeof properties["DataProtectionPolicy"] === "string" ? properties["DataProtectionPolicy"] : JSON.stringify(properties["DataProtectionPolicy"]);
|
|
7821
|
-
await this.logsClient.send(new PutDataProtectionPolicyCommand({
|
|
7822
|
-
logGroupIdentifier: logGroupName,
|
|
7823
|
-
policyDocument
|
|
7824
|
-
}));
|
|
7825
|
+
let createdNewLogGroup = false;
|
|
7826
|
+
try {
|
|
7827
|
+
await this.logsClient.send(new CreateLogGroupCommand(createParams));
|
|
7828
|
+
createdNewLogGroup = true;
|
|
7829
|
+
} catch (createError) {
|
|
7830
|
+
if (createError instanceof ResourceAlreadyExistsException) this.logger.debug(`Log group ${logGroupName} already exists, using existing`);
|
|
7831
|
+
else throw createError;
|
|
7825
7832
|
}
|
|
7826
|
-
|
|
7827
|
-
|
|
7828
|
-
if (
|
|
7829
|
-
|
|
7830
|
-
|
|
7831
|
-
|
|
7833
|
+
try {
|
|
7834
|
+
const retentionInDays = properties["RetentionInDays"];
|
|
7835
|
+
if (retentionInDays) await this.logsClient.send(new PutRetentionPolicyCommand({
|
|
7836
|
+
logGroupName,
|
|
7837
|
+
retentionInDays
|
|
7838
|
+
}));
|
|
7839
|
+
if (properties["DataProtectionPolicy"]) {
|
|
7840
|
+
const policyDocument = typeof properties["DataProtectionPolicy"] === "string" ? properties["DataProtectionPolicy"] : JSON.stringify(properties["DataProtectionPolicy"]);
|
|
7841
|
+
await this.logsClient.send(new PutDataProtectionPolicyCommand({
|
|
7842
|
+
logGroupIdentifier: logGroupName,
|
|
7843
|
+
policyDocument
|
|
7844
|
+
}));
|
|
7845
|
+
}
|
|
7846
|
+
const fieldIndexPolicies = properties["FieldIndexPolicies"];
|
|
7847
|
+
if (fieldIndexPolicies && fieldIndexPolicies.length > 0) {
|
|
7848
|
+
if (fieldIndexPolicies.length > 1) this.logger.debug(`Log group ${logicalId} declares ${fieldIndexPolicies.length} FieldIndexPolicies; AWS only supports one log-group-level field index policy. Applying the first.`);
|
|
7849
|
+
const first = fieldIndexPolicies[0];
|
|
7850
|
+
const policyDocument = typeof first === "string" ? first : JSON.stringify(first);
|
|
7851
|
+
await this.logsClient.send(new PutIndexPolicyCommand({
|
|
7852
|
+
logGroupIdentifier: logGroupName,
|
|
7853
|
+
policyDocument
|
|
7854
|
+
}));
|
|
7855
|
+
}
|
|
7856
|
+
if (properties["BearerTokenAuthenticationEnabled"] !== void 0) await this.logsClient.send(new PutBearerTokenAuthenticationCommand({
|
|
7832
7857
|
logGroupIdentifier: logGroupName,
|
|
7833
|
-
|
|
7858
|
+
bearerTokenAuthenticationEnabled: properties["BearerTokenAuthenticationEnabled"]
|
|
7834
7859
|
}));
|
|
7860
|
+
} catch (innerError) {
|
|
7861
|
+
if (createdNewLogGroup) try {
|
|
7862
|
+
await this.logsClient.send(new DeleteLogGroupCommand({ logGroupName }));
|
|
7863
|
+
this.logger.debug(`Cleaned up partially-created log group ${logicalId} (${logGroupName}) after wiring failure`);
|
|
7864
|
+
} catch (cleanupError) {
|
|
7865
|
+
this.logger.warn(`Failed to clean up partially-created log group ${logicalId} (${logGroupName}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws logs delete-log-group --log-group-name '${logGroupName}'`);
|
|
7866
|
+
}
|
|
7867
|
+
throw innerError;
|
|
7835
7868
|
}
|
|
7836
|
-
if (properties["BearerTokenAuthenticationEnabled"] !== void 0) await this.logsClient.send(new PutBearerTokenAuthenticationCommand({
|
|
7837
|
-
logGroupIdentifier: logGroupName,
|
|
7838
|
-
bearerTokenAuthenticationEnabled: properties["BearerTokenAuthenticationEnabled"]
|
|
7839
|
-
}));
|
|
7840
7869
|
this.logger.debug(`Successfully created log group ${logicalId}: ${logGroupName}`);
|
|
7841
7870
|
return {
|
|
7842
7871
|
physicalId: logGroupName,
|
|
7843
7872
|
attributes: { Arn: await this.buildArn(logGroupName) }
|
|
7844
7873
|
};
|
|
7845
7874
|
} catch (error) {
|
|
7846
|
-
if (error instanceof ResourceAlreadyExistsException) {
|
|
7847
|
-
this.logger.debug(`Log group ${logGroupName} already exists, using existing`);
|
|
7848
|
-
return {
|
|
7849
|
-
physicalId: logGroupName,
|
|
7850
|
-
attributes: { Arn: await this.buildArn(logGroupName) }
|
|
7851
|
-
};
|
|
7852
|
-
}
|
|
7853
7875
|
const cause = error instanceof Error ? error : void 0;
|
|
7854
7876
|
throw new ProvisioningError(`Failed to create log group ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, logGroupName, cause);
|
|
7855
7877
|
}
|
|
@@ -8756,16 +8778,26 @@ var SSMParameterProvider = class {
|
|
|
8756
8778
|
if (properties["Policies"]) putParams.Policies = properties["Policies"];
|
|
8757
8779
|
if (properties["DataType"]) putParams.DataType = properties["DataType"];
|
|
8758
8780
|
await this.ssmClient.send(new PutParameterCommand(putParams));
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
|
|
8765
|
-
|
|
8766
|
-
|
|
8767
|
-
|
|
8768
|
-
|
|
8781
|
+
try {
|
|
8782
|
+
if (properties["Tags"]) {
|
|
8783
|
+
const ssmTags = properties["Tags"].map((t) => ({
|
|
8784
|
+
Key: t.Key,
|
|
8785
|
+
Value: t.Value
|
|
8786
|
+
}));
|
|
8787
|
+
await this.ssmClient.send(new AddTagsToResourceCommand({
|
|
8788
|
+
ResourceType: "Parameter",
|
|
8789
|
+
ResourceId: name,
|
|
8790
|
+
Tags: ssmTags
|
|
8791
|
+
}));
|
|
8792
|
+
}
|
|
8793
|
+
} catch (innerError) {
|
|
8794
|
+
try {
|
|
8795
|
+
await this.ssmClient.send(new DeleteParameterCommand({ Name: name }));
|
|
8796
|
+
this.logger.debug(`Cleaned up partially-created SSM parameter ${logicalId} (${name}) after wiring failure`);
|
|
8797
|
+
} catch (cleanupError) {
|
|
8798
|
+
this.logger.warn(`Failed to clean up partially-created SSM parameter ${logicalId} (${name}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws ssm delete-parameter --name '${name}'`);
|
|
8799
|
+
}
|
|
8800
|
+
throw innerError;
|
|
8769
8801
|
}
|
|
8770
8802
|
this.logger.debug(`Successfully created SSM parameter ${logicalId}: ${name}`);
|
|
8771
8803
|
return {
|
|
@@ -12357,6 +12389,21 @@ var ApiGatewayProvider = class ApiGatewayProvider {
|
|
|
12357
12389
|
* `Invalid mapping expression specified: ... [No method response exists
|
|
12358
12390
|
* for method.]` — the canonical trigger is a CORS preflight OPTIONS
|
|
12359
12391
|
* method emitted by `RestApi({ defaultCorsPreflightOptions: ... })`.
|
|
12392
|
+
*
|
|
12393
|
+
* Partial-failure cleanup: if any AWS call AFTER `PutMethodCommand`
|
|
12394
|
+
* fails, the method has already been created on AWS but cdkd state
|
|
12395
|
+
* does NOT record it (the throw happens before the success return).
|
|
12396
|
+
* A subsequent redeploy would then attempt CREATE again and AWS would
|
|
12397
|
+
* reject with `Method already exists for this resource`. To prevent
|
|
12398
|
+
* this orphan, the post-`PutMethod` block is wrapped in an inner
|
|
12399
|
+
* try/catch that issues a best-effort `DeleteMethodCommand` before
|
|
12400
|
+
* re-throwing the original error. Cleanup failures are logged at warn
|
|
12401
|
+
* (the underlying create failure is what matters; we don't mask it by
|
|
12402
|
+
* promoting a cleanup error). The class of bug — partial AWS-side
|
|
12403
|
+
* commit on `createMethod` failure — was first seen via the
|
|
12404
|
+
* `PutIntegrationResponse`-before-`PutMethodResponse` ordering bug
|
|
12405
|
+
* fixed in PR #373; this cleanup makes any future shape of
|
|
12406
|
+
* post-`PutMethod` failure self-healing on the next redeploy.
|
|
12360
12407
|
*/
|
|
12361
12408
|
async createMethod(logicalId, resourceType, properties) {
|
|
12362
12409
|
this.logger.debug(`Creating API Gateway Method ${logicalId}`);
|
|
@@ -12386,54 +12433,68 @@ var ApiGatewayProvider = class ApiGatewayProvider {
|
|
|
12386
12433
|
requestValidatorId,
|
|
12387
12434
|
authorizationScopes
|
|
12388
12435
|
}));
|
|
12389
|
-
|
|
12390
|
-
|
|
12391
|
-
|
|
12392
|
-
resourceId,
|
|
12393
|
-
httpMethod,
|
|
12394
|
-
type: integration["Type"],
|
|
12395
|
-
integrationHttpMethod: integration["IntegrationHttpMethod"],
|
|
12396
|
-
uri: integration["Uri"],
|
|
12397
|
-
connectionType: integration["ConnectionType"],
|
|
12398
|
-
connectionId: integration["ConnectionId"],
|
|
12399
|
-
credentials: integration["Credentials"],
|
|
12400
|
-
requestParameters: integration["RequestParameters"],
|
|
12401
|
-
requestTemplates: integration["RequestTemplates"],
|
|
12402
|
-
passthroughBehavior: integration["PassthroughBehavior"],
|
|
12403
|
-
contentHandling: integration["ContentHandling"],
|
|
12404
|
-
timeoutInMillis: integration["TimeoutInMillis"],
|
|
12405
|
-
cacheNamespace: integration["CacheNamespace"],
|
|
12406
|
-
cacheKeyParameters: integration["CacheKeyParameters"],
|
|
12407
|
-
tlsConfig: integration["TlsConfig"] ? { insecureSkipVerification: integration["TlsConfig"]["InsecureSkipVerification"] } : void 0,
|
|
12408
|
-
responseTransferMode: integration["ResponseTransferMode"]
|
|
12409
|
-
}));
|
|
12410
|
-
const methodResponses = properties["MethodResponses"];
|
|
12411
|
-
if (methodResponses) for (const resp of methodResponses) {
|
|
12412
|
-
const statusCode = String(resp["StatusCode"]);
|
|
12413
|
-
await this.apiGatewayClient.send(new PutMethodResponseCommand({
|
|
12436
|
+
try {
|
|
12437
|
+
const integration = properties["Integration"];
|
|
12438
|
+
if (integration) await this.apiGatewayClient.send(new PutIntegrationCommand({
|
|
12414
12439
|
restApiId,
|
|
12415
12440
|
resourceId,
|
|
12416
12441
|
httpMethod,
|
|
12417
|
-
|
|
12418
|
-
|
|
12419
|
-
|
|
12442
|
+
type: integration["Type"],
|
|
12443
|
+
integrationHttpMethod: integration["IntegrationHttpMethod"],
|
|
12444
|
+
uri: integration["Uri"],
|
|
12445
|
+
connectionType: integration["ConnectionType"],
|
|
12446
|
+
connectionId: integration["ConnectionId"],
|
|
12447
|
+
credentials: integration["Credentials"],
|
|
12448
|
+
requestParameters: integration["RequestParameters"],
|
|
12449
|
+
requestTemplates: integration["RequestTemplates"],
|
|
12450
|
+
passthroughBehavior: integration["PassthroughBehavior"],
|
|
12451
|
+
contentHandling: integration["ContentHandling"],
|
|
12452
|
+
timeoutInMillis: integration["TimeoutInMillis"],
|
|
12453
|
+
cacheNamespace: integration["CacheNamespace"],
|
|
12454
|
+
cacheKeyParameters: integration["CacheKeyParameters"],
|
|
12455
|
+
tlsConfig: integration["TlsConfig"] ? { insecureSkipVerification: integration["TlsConfig"]["InsecureSkipVerification"] } : void 0,
|
|
12456
|
+
responseTransferMode: integration["ResponseTransferMode"]
|
|
12420
12457
|
}));
|
|
12421
|
-
|
|
12422
|
-
|
|
12423
|
-
|
|
12424
|
-
|
|
12425
|
-
const statusCode = String(ir["StatusCode"]);
|
|
12426
|
-
await this.apiGatewayClient.send(new PutIntegrationResponseCommand({
|
|
12458
|
+
const methodResponses = properties["MethodResponses"];
|
|
12459
|
+
if (methodResponses) for (const resp of methodResponses) {
|
|
12460
|
+
const statusCode = String(resp["StatusCode"]);
|
|
12461
|
+
await this.apiGatewayClient.send(new PutMethodResponseCommand({
|
|
12427
12462
|
restApiId,
|
|
12428
12463
|
resourceId,
|
|
12429
12464
|
httpMethod,
|
|
12430
12465
|
statusCode,
|
|
12431
|
-
|
|
12432
|
-
responseParameters:
|
|
12433
|
-
|
|
12434
|
-
|
|
12466
|
+
responseModels: resp["ResponseModels"],
|
|
12467
|
+
responseParameters: resp["ResponseParameters"]
|
|
12468
|
+
}));
|
|
12469
|
+
}
|
|
12470
|
+
if (integration) {
|
|
12471
|
+
const integrationResponses = integration["IntegrationResponses"];
|
|
12472
|
+
if (integrationResponses) for (const ir of integrationResponses) {
|
|
12473
|
+
const statusCode = String(ir["StatusCode"]);
|
|
12474
|
+
await this.apiGatewayClient.send(new PutIntegrationResponseCommand({
|
|
12475
|
+
restApiId,
|
|
12476
|
+
resourceId,
|
|
12477
|
+
httpMethod,
|
|
12478
|
+
statusCode,
|
|
12479
|
+
selectionPattern: ir["SelectionPattern"],
|
|
12480
|
+
responseParameters: ir["ResponseParameters"],
|
|
12481
|
+
responseTemplates: ir["ResponseTemplates"],
|
|
12482
|
+
contentHandling: ir["ContentHandling"]
|
|
12483
|
+
}));
|
|
12484
|
+
}
|
|
12485
|
+
}
|
|
12486
|
+
} catch (innerError) {
|
|
12487
|
+
try {
|
|
12488
|
+
await this.apiGatewayClient.send(new DeleteMethodCommand({
|
|
12489
|
+
restApiId,
|
|
12490
|
+
resourceId,
|
|
12491
|
+
httpMethod
|
|
12435
12492
|
}));
|
|
12493
|
+
this.logger.debug(`Cleaned up partially-created API Gateway Method ${logicalId} (${restApiId}/${resourceId}/${httpMethod}) after wiring failure`);
|
|
12494
|
+
} catch (cleanupError) {
|
|
12495
|
+
this.logger.warn(`Failed to clean up partially-created API Gateway Method ${logicalId} (${restApiId}/${resourceId}/${httpMethod}): ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}. Manual deletion may be required before the next deploy: aws apigateway delete-method --rest-api-id ${restApiId} --resource-id ${resourceId} --http-method ${httpMethod}`);
|
|
12436
12496
|
}
|
|
12497
|
+
throw innerError;
|
|
12437
12498
|
}
|
|
12438
12499
|
const physicalId = `${restApiId}|${resourceId}|${httpMethod}`;
|
|
12439
12500
|
this.logger.debug(`Successfully created API Gateway Method ${logicalId}: ${physicalId}`);
|
|
@@ -42709,7 +42770,7 @@ function reorderArgs(argv) {
|
|
|
42709
42770
|
*/
|
|
42710
42771
|
async function main() {
|
|
42711
42772
|
const program = new Command();
|
|
42712
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.102.
|
|
42773
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.102.3");
|
|
42713
42774
|
program.addCommand(createBootstrapCommand());
|
|
42714
42775
|
program.addCommand(createSynthCommand());
|
|
42715
42776
|
program.addCommand(createListCommand());
|