cdk-insights 0.4.6 → 0.4.8-beta.0
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/aspects/CdkInsightsAspect.js +14 -11
- package/dist/cli/entry.js +176 -82
- package/dist/cli/types/cli.types.d.ts +1 -1
- package/dist/helpers/serviceSelection/serviceSelection.d.ts +10 -0
- package/dist/helpers/serviceSelection/serviceSelection.test.d.ts +1 -0
- package/dist/index.js +128 -63
- package/dist/types/analysis.types.d.ts +3 -1
- package/package.json +1 -1
|
@@ -33691,7 +33691,7 @@ var require_branded_api_example = __commonJS({
|
|
|
33691
33691
|
var demonstrateBrandedAPI = () => {
|
|
33692
33692
|
const env = (0, index_1.getEnvironment)();
|
|
33693
33693
|
const formatter = (0, index_1.createJsonFormatter)();
|
|
33694
|
-
const
|
|
33694
|
+
const consoleTransport2 = (0, index_1.createStroggerConsoleTransport)({
|
|
33695
33695
|
formatter,
|
|
33696
33696
|
level: index_1.LogLevel.DEBUG
|
|
33697
33697
|
});
|
|
@@ -33705,7 +33705,7 @@ var require_branded_api_example = __commonJS({
|
|
|
33705
33705
|
serviceName: "branded-api-demo",
|
|
33706
33706
|
stage: env.stage
|
|
33707
33707
|
},
|
|
33708
|
-
transports: [
|
|
33708
|
+
transports: [consoleTransport2, dataDogTransport],
|
|
33709
33709
|
formatter,
|
|
33710
33710
|
env
|
|
33711
33711
|
});
|
|
@@ -33995,23 +33995,26 @@ var import_cdk_nag = require("cdk-nag");
|
|
|
33995
33995
|
var import_strogger = __toESM(require_dist());
|
|
33996
33996
|
var isDevelopment = process.env.NODE_ENV === "development";
|
|
33997
33997
|
var isDebugEnabled = process.env.CDK_INSIGHTS_DEBUG === "true" || process.env.CDK_INSIGHTS_VERBOSE === "true";
|
|
33998
|
+
var isConsoleLoggingEnabled = isDevelopment || isDebugEnabled || process.env.CDK_INSIGHTS_ENABLE_LOGGING === "true";
|
|
33999
|
+
var defaultLogLevel = isDebugEnabled ? import_strogger.LogLevel.DEBUG : isDevelopment ? import_strogger.LogLevel.INFO : import_strogger.LogLevel.ERROR;
|
|
34000
|
+
var consoleTransport = isConsoleLoggingEnabled ? [
|
|
34001
|
+
(0, import_strogger.createConsoleTransport)({
|
|
34002
|
+
formatter: (0, import_strogger.createJsonFormatter)(),
|
|
34003
|
+
level: defaultLogLevel,
|
|
34004
|
+
useColors: !isDevelopment
|
|
34005
|
+
})
|
|
34006
|
+
] : [];
|
|
33998
34007
|
var logger3 = (0, import_strogger.createLogger)({
|
|
33999
34008
|
config: {
|
|
34000
|
-
level:
|
|
34009
|
+
level: defaultLogLevel,
|
|
34001
34010
|
serviceName: "cdk-insights",
|
|
34002
34011
|
stage: isDevelopment ? "dev" : "prod"
|
|
34003
34012
|
},
|
|
34004
34013
|
formatter: (0, import_strogger.createJsonFormatter)(),
|
|
34005
|
-
transports:
|
|
34006
|
-
(0, import_strogger.createConsoleTransport)({
|
|
34007
|
-
formatter: (0, import_strogger.createJsonFormatter)(),
|
|
34008
|
-
level: isDebugEnabled ? import_strogger.LogLevel.DEBUG : isDevelopment ? import_strogger.LogLevel.INFO : import_strogger.LogLevel.WARN,
|
|
34009
|
-
useColors: !isDevelopment
|
|
34010
|
-
})
|
|
34011
|
-
],
|
|
34014
|
+
transports: consoleTransport,
|
|
34012
34015
|
env: {
|
|
34013
34016
|
STAGE: isDevelopment ? "dev" : "prod",
|
|
34014
|
-
LOG_LEVEL: isDebugEnabled ? "DEBUG" : isDevelopment ? "INFO" : "
|
|
34017
|
+
LOG_LEVEL: isDebugEnabled ? "DEBUG" : isDevelopment ? "INFO" : "ERROR"
|
|
34015
34018
|
}
|
|
34016
34019
|
});
|
|
34017
34020
|
var createComponentLogger = (component) => ({
|
package/dist/cli/entry.js
CHANGED
|
@@ -35831,7 +35831,7 @@ var require_branded_api_example = __commonJS({
|
|
|
35831
35831
|
var demonstrateBrandedAPI = () => {
|
|
35832
35832
|
const env4 = (0, index_1.getEnvironment)();
|
|
35833
35833
|
const formatter = (0, index_1.createJsonFormatter)();
|
|
35834
|
-
const
|
|
35834
|
+
const consoleTransport2 = (0, index_1.createStroggerConsoleTransport)({
|
|
35835
35835
|
formatter,
|
|
35836
35836
|
level: index_1.LogLevel.DEBUG
|
|
35837
35837
|
});
|
|
@@ -35845,7 +35845,7 @@ var require_branded_api_example = __commonJS({
|
|
|
35845
35845
|
serviceName: "branded-api-demo",
|
|
35846
35846
|
stage: env4.stage
|
|
35847
35847
|
},
|
|
35848
|
-
transports: [
|
|
35848
|
+
transports: [consoleTransport2, dataDogTransport],
|
|
35849
35849
|
formatter,
|
|
35850
35850
|
env: env4
|
|
35851
35851
|
});
|
|
@@ -78612,23 +78612,26 @@ var getFeatureUpgradeMessage = (feature, tier, context) => {
|
|
|
78612
78612
|
var import_strogger = __toESM(require_dist());
|
|
78613
78613
|
var isDevelopment = process.env.NODE_ENV === "development";
|
|
78614
78614
|
var isDebugEnabled = process.env.CDK_INSIGHTS_DEBUG === "true" || process.env.CDK_INSIGHTS_VERBOSE === "true";
|
|
78615
|
+
var isConsoleLoggingEnabled = isDevelopment || isDebugEnabled || process.env.CDK_INSIGHTS_ENABLE_LOGGING === "true";
|
|
78616
|
+
var defaultLogLevel = isDebugEnabled ? import_strogger.LogLevel.DEBUG : isDevelopment ? import_strogger.LogLevel.INFO : import_strogger.LogLevel.ERROR;
|
|
78617
|
+
var consoleTransport = isConsoleLoggingEnabled ? [
|
|
78618
|
+
(0, import_strogger.createConsoleTransport)({
|
|
78619
|
+
formatter: (0, import_strogger.createJsonFormatter)(),
|
|
78620
|
+
level: defaultLogLevel,
|
|
78621
|
+
useColors: !isDevelopment
|
|
78622
|
+
})
|
|
78623
|
+
] : [];
|
|
78615
78624
|
var logger3 = (0, import_strogger.createLogger)({
|
|
78616
78625
|
config: {
|
|
78617
|
-
level:
|
|
78626
|
+
level: defaultLogLevel,
|
|
78618
78627
|
serviceName: "cdk-insights",
|
|
78619
78628
|
stage: isDevelopment ? "dev" : "prod"
|
|
78620
78629
|
},
|
|
78621
78630
|
formatter: (0, import_strogger.createJsonFormatter)(),
|
|
78622
|
-
transports:
|
|
78623
|
-
(0, import_strogger.createConsoleTransport)({
|
|
78624
|
-
formatter: (0, import_strogger.createJsonFormatter)(),
|
|
78625
|
-
level: isDebugEnabled ? import_strogger.LogLevel.DEBUG : isDevelopment ? import_strogger.LogLevel.INFO : import_strogger.LogLevel.WARN,
|
|
78626
|
-
useColors: !isDevelopment
|
|
78627
|
-
})
|
|
78628
|
-
],
|
|
78631
|
+
transports: consoleTransport,
|
|
78629
78632
|
env: {
|
|
78630
78633
|
STAGE: isDevelopment ? "dev" : "prod",
|
|
78631
|
-
LOG_LEVEL: isDebugEnabled ? "DEBUG" : isDevelopment ? "INFO" : "
|
|
78634
|
+
LOG_LEVEL: isDebugEnabled ? "DEBUG" : isDevelopment ? "INFO" : "ERROR"
|
|
78632
78635
|
}
|
|
78633
78636
|
});
|
|
78634
78637
|
var createComponentLogger = (component) => ({
|
|
@@ -78757,6 +78760,107 @@ var recordCacheSet = () => {
|
|
|
78757
78760
|
saveCacheStats();
|
|
78758
78761
|
};
|
|
78759
78762
|
|
|
78763
|
+
// src/helpers/serviceSelection/serviceSelection.ts
|
|
78764
|
+
var SPECIFIC_SERVICE_NAMES = [
|
|
78765
|
+
"IAM",
|
|
78766
|
+
"S3",
|
|
78767
|
+
"Lambda",
|
|
78768
|
+
"DynamoDB",
|
|
78769
|
+
"RDS",
|
|
78770
|
+
"EC2",
|
|
78771
|
+
"SNS",
|
|
78772
|
+
"SQS",
|
|
78773
|
+
"StepFunctions",
|
|
78774
|
+
"CloudTrail",
|
|
78775
|
+
"ApiGateway",
|
|
78776
|
+
"SecretsManager",
|
|
78777
|
+
"KMS",
|
|
78778
|
+
"EventBridge"
|
|
78779
|
+
];
|
|
78780
|
+
var SERVICE_NAME_TO_CHECK_KEYS = {
|
|
78781
|
+
IAM: ["iamPolicies"],
|
|
78782
|
+
S3: ["s3Buckets", "s3IntelligentTiering"],
|
|
78783
|
+
Lambda: ["lambdaEnvironmentVariables", "lambdaMemory"],
|
|
78784
|
+
DynamoDB: ["dynamoDBAutoScaling", "dynamoDBStreams"],
|
|
78785
|
+
RDS: ["rdsEncryption", "rdsMultiAZ"],
|
|
78786
|
+
EC2: ["ec2InstanceType", "natGatewayUsage", "securityGroups", "ebsUnusedVolumes"],
|
|
78787
|
+
SNS: ["sns"],
|
|
78788
|
+
SQS: ["sqs"],
|
|
78789
|
+
StepFunctions: ["stepFunctions"],
|
|
78790
|
+
CloudTrail: ["cloudTrailLogging"],
|
|
78791
|
+
ApiGateway: ["apiGateway"],
|
|
78792
|
+
SecretsManager: ["secretsManager"],
|
|
78793
|
+
KMS: ["kmsKeys"],
|
|
78794
|
+
EventBridge: ["eventBridgeRules"]
|
|
78795
|
+
};
|
|
78796
|
+
var CHECK_KEY_TO_SERVICE_NAME = Object.entries(
|
|
78797
|
+
SERVICE_NAME_TO_CHECK_KEYS
|
|
78798
|
+
).reduce((acc, [service, keys]) => {
|
|
78799
|
+
for (const key of keys) {
|
|
78800
|
+
acc[key] = service;
|
|
78801
|
+
}
|
|
78802
|
+
return acc;
|
|
78803
|
+
}, {});
|
|
78804
|
+
var dedupe = (items) => {
|
|
78805
|
+
const seen = /* @__PURE__ */ new Set();
|
|
78806
|
+
const result = [];
|
|
78807
|
+
for (const item of items) {
|
|
78808
|
+
if (seen.has(item)) {
|
|
78809
|
+
continue;
|
|
78810
|
+
}
|
|
78811
|
+
seen.add(item);
|
|
78812
|
+
result.push(item);
|
|
78813
|
+
}
|
|
78814
|
+
return result;
|
|
78815
|
+
};
|
|
78816
|
+
var normalizeServiceSelection = (services) => {
|
|
78817
|
+
if (!services || services.length === 0) {
|
|
78818
|
+
return {
|
|
78819
|
+
services: ["All services"],
|
|
78820
|
+
removedAllServices: false,
|
|
78821
|
+
defaultedToAll: true
|
|
78822
|
+
};
|
|
78823
|
+
}
|
|
78824
|
+
const uniqueServices = dedupe(services);
|
|
78825
|
+
const hasAllServices = uniqueServices.includes("All services");
|
|
78826
|
+
const specificServices = uniqueServices.filter(
|
|
78827
|
+
(service) => service !== "All services"
|
|
78828
|
+
);
|
|
78829
|
+
if (hasAllServices && specificServices.length > 0) {
|
|
78830
|
+
return {
|
|
78831
|
+
services: specificServices,
|
|
78832
|
+
removedAllServices: true,
|
|
78833
|
+
defaultedToAll: false
|
|
78834
|
+
};
|
|
78835
|
+
}
|
|
78836
|
+
return {
|
|
78837
|
+
services: hasAllServices ? ["All services"] : uniqueServices,
|
|
78838
|
+
removedAllServices: false,
|
|
78839
|
+
defaultedToAll: false
|
|
78840
|
+
};
|
|
78841
|
+
};
|
|
78842
|
+
var mapServicesToCheckKeys = (services, allCheckKeys) => {
|
|
78843
|
+
if (services.length === 0 || services.includes("All services")) {
|
|
78844
|
+
return dedupe(allCheckKeys);
|
|
78845
|
+
}
|
|
78846
|
+
const resolvedKeys = services.flatMap((service) => {
|
|
78847
|
+
if (service === "All services") {
|
|
78848
|
+
return allCheckKeys;
|
|
78849
|
+
}
|
|
78850
|
+
return SERVICE_NAME_TO_CHECK_KEYS[service] ?? [];
|
|
78851
|
+
});
|
|
78852
|
+
return dedupe(resolvedKeys);
|
|
78853
|
+
};
|
|
78854
|
+
var getServiceLabelForCheckKey = (checkKey) => {
|
|
78855
|
+
return CHECK_KEY_TO_SERVICE_NAME[checkKey];
|
|
78856
|
+
};
|
|
78857
|
+
var isServiceName = (value) => {
|
|
78858
|
+
if (value === "All services") {
|
|
78859
|
+
return true;
|
|
78860
|
+
}
|
|
78861
|
+
return SPECIFIC_SERVICE_NAMES.includes(value);
|
|
78862
|
+
};
|
|
78863
|
+
|
|
78760
78864
|
// node_modules/axios/lib/helpers/bind.js
|
|
78761
78865
|
function bind(fn, thisArg) {
|
|
78762
78866
|
return function wrap2() {
|
|
@@ -90323,25 +90427,6 @@ var memoizedServiceChecks = memoize(createAWSServiceChecks, {
|
|
|
90323
90427
|
// 10 minutes
|
|
90324
90428
|
maxSize: 10
|
|
90325
90429
|
});
|
|
90326
|
-
var getServiceCheckKeys = (serviceName) => {
|
|
90327
|
-
const serviceMapping = {
|
|
90328
|
-
"Lambda": ["lambdaEnvironmentVariables", "lambdaMemory"],
|
|
90329
|
-
"S3": ["s3Buckets", "s3IntelligentTiering"],
|
|
90330
|
-
"DynamoDB": ["dynamoDBAutoScaling", "dynamoDBStreams"],
|
|
90331
|
-
"RDS": ["rdsEncryption", "rdsMultiAZ"],
|
|
90332
|
-
"EC2": ["ec2InstanceType", "natGatewayUsage", "securityGroups", "ebsUnusedVolumes"],
|
|
90333
|
-
"IAM": ["iamPolicies"],
|
|
90334
|
-
"SNS": ["sns"],
|
|
90335
|
-
"SQS": ["sqs"],
|
|
90336
|
-
"StepFunctions": ["stepFunctions"],
|
|
90337
|
-
"CloudTrail": ["cloudTrailLogging"],
|
|
90338
|
-
"ApiGateway": ["apiGateway"],
|
|
90339
|
-
"SecretsManager": ["secretsManager"],
|
|
90340
|
-
"KMS": ["kmsKeys"],
|
|
90341
|
-
"EventBridge": ["eventBridgeRules"]
|
|
90342
|
-
};
|
|
90343
|
-
return serviceMapping[serviceName] || [serviceName];
|
|
90344
|
-
};
|
|
90345
90430
|
var createResourceFilter = (selectedServices) => {
|
|
90346
90431
|
if (selectedServices.includes("All services")) {
|
|
90347
90432
|
return (cloudFormationResource) => !cloudFormationResource.Type.startsWith("AWS::CDK::");
|
|
@@ -90358,13 +90443,16 @@ var createResourceFilter = (selectedServices) => {
|
|
|
90358
90443
|
};
|
|
90359
90444
|
var runStaticAnalysis = (cloudformationTemplate, createFinding2, selectedServices = [], solutionsRegistry = {}) => {
|
|
90360
90445
|
const serviceChecks = memoizedServiceChecks();
|
|
90361
|
-
const allServiceKeys = Object.keys(serviceChecks)
|
|
90362
|
-
const servicesToAnalyze = selectedServices.length > 0 && !selectedServices.includes("All services") ? selectedServices : allServiceKeys.filter(
|
|
90446
|
+
const allServiceKeys = Object.keys(serviceChecks).filter(
|
|
90363
90447
|
(serviceKey) => serviceKey !== "solutionsPatterns"
|
|
90364
90448
|
);
|
|
90365
|
-
const
|
|
90449
|
+
const { services: normalizedServices } = normalizeServiceSelection(selectedServices);
|
|
90450
|
+
const servicesToAnalyze = mapServicesToCheckKeys(
|
|
90451
|
+
normalizedServices,
|
|
90452
|
+
allServiceKeys
|
|
90453
|
+
);
|
|
90366
90454
|
const analysisFindings = {};
|
|
90367
|
-
const resourceFilter = createResourceFilter(
|
|
90455
|
+
const resourceFilter = createResourceFilter(normalizedServices);
|
|
90368
90456
|
const userResources = Object.entries(cloudformationTemplate.Resources || {}).filter(
|
|
90369
90457
|
([, cloudFormationResource]) => resourceFilter(cloudFormationResource)
|
|
90370
90458
|
).reduce(
|
|
@@ -90374,37 +90462,36 @@ var runStaticAnalysis = (cloudformationTemplate, createFinding2, selectedService
|
|
|
90374
90462
|
},
|
|
90375
90463
|
{}
|
|
90376
90464
|
);
|
|
90377
|
-
for (const
|
|
90378
|
-
|
|
90379
|
-
|
|
90380
|
-
|
|
90381
|
-
const
|
|
90382
|
-
|
|
90383
|
-
|
|
90384
|
-
analysisLogger.warn(
|
|
90385
|
-
`\u26A0\uFE0F Service check function for ${serviceName} is not available`
|
|
90386
|
-
);
|
|
90387
|
-
}
|
|
90388
|
-
continue;
|
|
90389
|
-
}
|
|
90390
|
-
const typedServiceCheckFunction = serviceCheckFunction;
|
|
90391
|
-
const serviceAnalysisResult = typedServiceCheckFunction(
|
|
90392
|
-
{ Resources: userResources },
|
|
90393
|
-
createFinding2
|
|
90465
|
+
for (const checkKey of servicesToAnalyze) {
|
|
90466
|
+
try {
|
|
90467
|
+
const serviceCheckFunction = serviceChecks[checkKey];
|
|
90468
|
+
if (typeof serviceCheckFunction !== "function") {
|
|
90469
|
+
const serviceLabel = getServiceLabelForCheckKey(checkKey) ?? checkKey;
|
|
90470
|
+
analysisLogger.warn(
|
|
90471
|
+
`\u26A0\uFE0F Service check function for ${serviceLabel} (${checkKey}) is not available`
|
|
90394
90472
|
);
|
|
90395
|
-
|
|
90396
|
-
serviceAnalysisResult
|
|
90397
|
-
)) {
|
|
90398
|
-
if (!analysisFindings[resourceName]) {
|
|
90399
|
-
analysisFindings[resourceName] = { issues: [] };
|
|
90400
|
-
}
|
|
90401
|
-
analysisFindings[resourceName].issues.push(...resourceFindings.issues);
|
|
90402
|
-
}
|
|
90403
|
-
} catch (analysisError) {
|
|
90404
|
-
analysisLogger.warn(`\u26A0\uFE0F Error in ${serviceName} analysis (${checkKey})`, {
|
|
90405
|
-
error: analysisError instanceof Error ? analysisError.message : String(analysisError)
|
|
90406
|
-
});
|
|
90473
|
+
continue;
|
|
90407
90474
|
}
|
|
90475
|
+
const serviceAnalysisResult = serviceCheckFunction(
|
|
90476
|
+
{ Resources: userResources },
|
|
90477
|
+
createFinding2
|
|
90478
|
+
);
|
|
90479
|
+
for (const [resourceName, resourceFindings] of Object.entries(
|
|
90480
|
+
serviceAnalysisResult
|
|
90481
|
+
)) {
|
|
90482
|
+
if (!analysisFindings[resourceName]) {
|
|
90483
|
+
analysisFindings[resourceName] = { issues: [] };
|
|
90484
|
+
}
|
|
90485
|
+
analysisFindings[resourceName].issues.push(...resourceFindings.issues);
|
|
90486
|
+
}
|
|
90487
|
+
} catch (analysisError) {
|
|
90488
|
+
const serviceLabel = getServiceLabelForCheckKey(checkKey) ?? checkKey;
|
|
90489
|
+
analysisLogger.warn(
|
|
90490
|
+
`\u26A0\uFE0F Error in ${serviceLabel} analysis (${checkKey})`,
|
|
90491
|
+
{
|
|
90492
|
+
error: analysisError instanceof Error ? analysisError.message : String(analysisError)
|
|
90493
|
+
}
|
|
90494
|
+
);
|
|
90408
90495
|
}
|
|
90409
90496
|
}
|
|
90410
90497
|
if (Object.keys(solutionsRegistry).length > 0) {
|
|
@@ -94079,6 +94166,12 @@ var validateServices = (services) => {
|
|
|
94079
94166
|
}
|
|
94080
94167
|
return [];
|
|
94081
94168
|
};
|
|
94169
|
+
var validateServiceNames = (services) => {
|
|
94170
|
+
const parsed = validateServices(services);
|
|
94171
|
+
return parsed.map((service) => service.trim()).filter(Boolean).map(
|
|
94172
|
+
(service) => service.toLowerCase() === "all" ? "All services" : service
|
|
94173
|
+
).filter((service) => isServiceName(service));
|
|
94174
|
+
};
|
|
94082
94175
|
var validateCacheConfig = (cache3) => {
|
|
94083
94176
|
if (!cache3 || typeof cache3 !== "object" || Array.isArray(cache3)) {
|
|
94084
94177
|
return DEFAULT_CONFIG.cache;
|
|
@@ -94132,7 +94225,7 @@ var mergeConfigWithArgs = (config2, cliArgs) => {
|
|
|
94132
94225
|
output: validatedOutput,
|
|
94133
94226
|
format: validatedOutput,
|
|
94134
94227
|
// Keep format in sync with output
|
|
94135
|
-
services:
|
|
94228
|
+
services: validateServiceNames(
|
|
94136
94229
|
cliArgs.services ?? config2.services ?? DEFAULT_CONFIG.services
|
|
94137
94230
|
),
|
|
94138
94231
|
withIssue,
|
|
@@ -94202,9 +94295,9 @@ var validateConfig = (config2) => {
|
|
|
94202
94295
|
);
|
|
94203
94296
|
}
|
|
94204
94297
|
if (Array.isArray(raw.services)) {
|
|
94205
|
-
validated.services = raw.services.filter(
|
|
94206
|
-
(
|
|
94207
|
-
);
|
|
94298
|
+
validated.services = raw.services.filter((s3) => typeof s3 === "string").map(
|
|
94299
|
+
(service) => service.toLowerCase() === "all" ? "All services" : service
|
|
94300
|
+
).filter((service) => isServiceName(service));
|
|
94208
94301
|
}
|
|
94209
94302
|
if (typeof raw.withIssue === "boolean") {
|
|
94210
94303
|
validated.withIssue = raw.withIssue;
|
|
@@ -94571,12 +94664,14 @@ async function runStackAnalysis(finalConfig, fingerprint, authToken, licenseInfo
|
|
|
94571
94664
|
throw refreshError;
|
|
94572
94665
|
}
|
|
94573
94666
|
} : void 0;
|
|
94574
|
-
|
|
94575
|
-
const
|
|
94576
|
-
|
|
94577
|
-
|
|
94578
|
-
|
|
94579
|
-
|
|
94667
|
+
const serviceSelection = normalizeServiceSelection(finalConfig.services);
|
|
94668
|
+
const selectedServices = serviceSelection.services;
|
|
94669
|
+
if (serviceSelection.removedAllServices) {
|
|
94670
|
+
cliLogger.debug(
|
|
94671
|
+
`Services normalization: removed "All services", using: ${selectedServices.join(", ")}`
|
|
94672
|
+
);
|
|
94673
|
+
} else if (serviceSelection.defaultedToAll) {
|
|
94674
|
+
cliLogger.debug('Services normalization: defaulting to "All services"');
|
|
94580
94675
|
}
|
|
94581
94676
|
const analysisConfig = {
|
|
94582
94677
|
stacks,
|
|
@@ -94719,14 +94814,6 @@ var analyzeCommand = {
|
|
|
94719
94814
|
if (isInteractive2 && !initialConfig.yes) {
|
|
94720
94815
|
const answers = await promptForConfig(initialConfig, stackChoices);
|
|
94721
94816
|
finalConfig = { ...initialConfig, ...answers };
|
|
94722
|
-
if (finalConfig.services && finalConfig.services.length > 0) {
|
|
94723
|
-
const hasAllServices = finalConfig.services.includes("All services");
|
|
94724
|
-
const hasOtherServices = finalConfig.services.some((s3) => s3 !== "All services");
|
|
94725
|
-
if (hasAllServices && hasOtherServices) {
|
|
94726
|
-
finalConfig.services = finalConfig.services.filter((s3) => s3 !== "All services");
|
|
94727
|
-
cliLogger.debug(`Normalized services: removed "All services", using specific services: ${finalConfig.services.join(", ")}`);
|
|
94728
|
-
}
|
|
94729
|
-
}
|
|
94730
94817
|
}
|
|
94731
94818
|
if (finalConfig.all) {
|
|
94732
94819
|
finalConfig.stackName = "All stacks";
|
|
@@ -95107,7 +95194,14 @@ var handleConfigSetup = async () => {
|
|
|
95107
95194
|
`Services to scan (comma-separated, or "all") [${cfg.services?.join(",") || "all"}]: `
|
|
95108
95195
|
);
|
|
95109
95196
|
if (services.trim()) {
|
|
95110
|
-
|
|
95197
|
+
if (services.trim().toLowerCase() === "all") {
|
|
95198
|
+
cfg.services = [];
|
|
95199
|
+
} else {
|
|
95200
|
+
const parsedServices = services.trim().split(",").map((s3) => s3.trim()).map(
|
|
95201
|
+
(service) => service.toLowerCase() === "all" ? "All services" : service
|
|
95202
|
+
).filter((service) => isServiceName(service));
|
|
95203
|
+
cfg.services = parsedServices;
|
|
95204
|
+
}
|
|
95111
95205
|
}
|
|
95112
95206
|
console.log("\n\u{1F4BE} Cache configuration:");
|
|
95113
95207
|
const cacheEnabled = await question(
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ServiceCheckKey, ServiceName, SpecificServiceName } from '../../types/analysis.types';
|
|
2
|
+
export declare const SPECIFIC_SERVICE_NAMES: readonly ["IAM", "S3", "Lambda", "DynamoDB", "RDS", "EC2", "SNS", "SQS", "StepFunctions", "CloudTrail", "ApiGateway", "SecretsManager", "KMS", "EventBridge"];
|
|
3
|
+
export declare const normalizeServiceSelection: (services?: ServiceName[]) => {
|
|
4
|
+
services: ServiceName[];
|
|
5
|
+
removedAllServices: boolean;
|
|
6
|
+
defaultedToAll: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare const mapServicesToCheckKeys: (services: ServiceName[], allCheckKeys: ServiceCheckKey[]) => ServiceCheckKey[];
|
|
9
|
+
export declare const getServiceLabelForCheckKey: (checkKey: ServiceCheckKey) => SpecificServiceName | undefined;
|
|
10
|
+
export declare const isServiceName: (value: string) => value is ServiceName;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
CHANGED
|
@@ -45306,7 +45306,7 @@ var require_branded_api_example = __commonJS({
|
|
|
45306
45306
|
var demonstrateBrandedAPI = () => {
|
|
45307
45307
|
const env2 = (0, index_1.getEnvironment)();
|
|
45308
45308
|
const formatter = (0, index_1.createJsonFormatter)();
|
|
45309
|
-
const
|
|
45309
|
+
const consoleTransport2 = (0, index_1.createStroggerConsoleTransport)({
|
|
45310
45310
|
formatter,
|
|
45311
45311
|
level: index_1.LogLevel.DEBUG
|
|
45312
45312
|
});
|
|
@@ -45320,7 +45320,7 @@ var require_branded_api_example = __commonJS({
|
|
|
45320
45320
|
serviceName: "branded-api-demo",
|
|
45321
45321
|
stage: env2.stage
|
|
45322
45322
|
},
|
|
45323
|
-
transports: [
|
|
45323
|
+
transports: [consoleTransport2, dataDogTransport],
|
|
45324
45324
|
formatter,
|
|
45325
45325
|
env: env2
|
|
45326
45326
|
});
|
|
@@ -54682,27 +54682,109 @@ var memoize = (functionToMemoize, options = {}) => {
|
|
|
54682
54682
|
};
|
|
54683
54683
|
};
|
|
54684
54684
|
|
|
54685
|
+
// src/helpers/serviceSelection/serviceSelection.ts
|
|
54686
|
+
var SERVICE_NAME_TO_CHECK_KEYS = {
|
|
54687
|
+
IAM: ["iamPolicies"],
|
|
54688
|
+
S3: ["s3Buckets", "s3IntelligentTiering"],
|
|
54689
|
+
Lambda: ["lambdaEnvironmentVariables", "lambdaMemory"],
|
|
54690
|
+
DynamoDB: ["dynamoDBAutoScaling", "dynamoDBStreams"],
|
|
54691
|
+
RDS: ["rdsEncryption", "rdsMultiAZ"],
|
|
54692
|
+
EC2: ["ec2InstanceType", "natGatewayUsage", "securityGroups", "ebsUnusedVolumes"],
|
|
54693
|
+
SNS: ["sns"],
|
|
54694
|
+
SQS: ["sqs"],
|
|
54695
|
+
StepFunctions: ["stepFunctions"],
|
|
54696
|
+
CloudTrail: ["cloudTrailLogging"],
|
|
54697
|
+
ApiGateway: ["apiGateway"],
|
|
54698
|
+
SecretsManager: ["secretsManager"],
|
|
54699
|
+
KMS: ["kmsKeys"],
|
|
54700
|
+
EventBridge: ["eventBridgeRules"]
|
|
54701
|
+
};
|
|
54702
|
+
var CHECK_KEY_TO_SERVICE_NAME = Object.entries(
|
|
54703
|
+
SERVICE_NAME_TO_CHECK_KEYS
|
|
54704
|
+
).reduce((acc, [service, keys]) => {
|
|
54705
|
+
for (const key of keys) {
|
|
54706
|
+
acc[key] = service;
|
|
54707
|
+
}
|
|
54708
|
+
return acc;
|
|
54709
|
+
}, {});
|
|
54710
|
+
var dedupe = (items) => {
|
|
54711
|
+
const seen = /* @__PURE__ */ new Set();
|
|
54712
|
+
const result = [];
|
|
54713
|
+
for (const item of items) {
|
|
54714
|
+
if (seen.has(item)) {
|
|
54715
|
+
continue;
|
|
54716
|
+
}
|
|
54717
|
+
seen.add(item);
|
|
54718
|
+
result.push(item);
|
|
54719
|
+
}
|
|
54720
|
+
return result;
|
|
54721
|
+
};
|
|
54722
|
+
var normalizeServiceSelection = (services) => {
|
|
54723
|
+
if (!services || services.length === 0) {
|
|
54724
|
+
return {
|
|
54725
|
+
services: ["All services"],
|
|
54726
|
+
removedAllServices: false,
|
|
54727
|
+
defaultedToAll: true
|
|
54728
|
+
};
|
|
54729
|
+
}
|
|
54730
|
+
const uniqueServices = dedupe(services);
|
|
54731
|
+
const hasAllServices = uniqueServices.includes("All services");
|
|
54732
|
+
const specificServices = uniqueServices.filter(
|
|
54733
|
+
(service) => service !== "All services"
|
|
54734
|
+
);
|
|
54735
|
+
if (hasAllServices && specificServices.length > 0) {
|
|
54736
|
+
return {
|
|
54737
|
+
services: specificServices,
|
|
54738
|
+
removedAllServices: true,
|
|
54739
|
+
defaultedToAll: false
|
|
54740
|
+
};
|
|
54741
|
+
}
|
|
54742
|
+
return {
|
|
54743
|
+
services: hasAllServices ? ["All services"] : uniqueServices,
|
|
54744
|
+
removedAllServices: false,
|
|
54745
|
+
defaultedToAll: false
|
|
54746
|
+
};
|
|
54747
|
+
};
|
|
54748
|
+
var mapServicesToCheckKeys = (services, allCheckKeys) => {
|
|
54749
|
+
if (services.length === 0 || services.includes("All services")) {
|
|
54750
|
+
return dedupe(allCheckKeys);
|
|
54751
|
+
}
|
|
54752
|
+
const resolvedKeys = services.flatMap((service) => {
|
|
54753
|
+
if (service === "All services") {
|
|
54754
|
+
return allCheckKeys;
|
|
54755
|
+
}
|
|
54756
|
+
return SERVICE_NAME_TO_CHECK_KEYS[service] ?? [];
|
|
54757
|
+
});
|
|
54758
|
+
return dedupe(resolvedKeys);
|
|
54759
|
+
};
|
|
54760
|
+
var getServiceLabelForCheckKey = (checkKey) => {
|
|
54761
|
+
return CHECK_KEY_TO_SERVICE_NAME[checkKey];
|
|
54762
|
+
};
|
|
54763
|
+
|
|
54685
54764
|
// src/shared/logger.ts
|
|
54686
54765
|
var import_strogger = __toESM(require_dist());
|
|
54687
54766
|
var isDevelopment = process.env.NODE_ENV === "development";
|
|
54688
54767
|
var isDebugEnabled = process.env.CDK_INSIGHTS_DEBUG === "true" || process.env.CDK_INSIGHTS_VERBOSE === "true";
|
|
54768
|
+
var isConsoleLoggingEnabled = isDevelopment || isDebugEnabled || process.env.CDK_INSIGHTS_ENABLE_LOGGING === "true";
|
|
54769
|
+
var defaultLogLevel = isDebugEnabled ? import_strogger.LogLevel.DEBUG : isDevelopment ? import_strogger.LogLevel.INFO : import_strogger.LogLevel.ERROR;
|
|
54770
|
+
var consoleTransport = isConsoleLoggingEnabled ? [
|
|
54771
|
+
(0, import_strogger.createConsoleTransport)({
|
|
54772
|
+
formatter: (0, import_strogger.createJsonFormatter)(),
|
|
54773
|
+
level: defaultLogLevel,
|
|
54774
|
+
useColors: !isDevelopment
|
|
54775
|
+
})
|
|
54776
|
+
] : [];
|
|
54689
54777
|
var logger3 = (0, import_strogger.createLogger)({
|
|
54690
54778
|
config: {
|
|
54691
|
-
level:
|
|
54779
|
+
level: defaultLogLevel,
|
|
54692
54780
|
serviceName: "cdk-insights",
|
|
54693
54781
|
stage: isDevelopment ? "dev" : "prod"
|
|
54694
54782
|
},
|
|
54695
54783
|
formatter: (0, import_strogger.createJsonFormatter)(),
|
|
54696
|
-
transports:
|
|
54697
|
-
(0, import_strogger.createConsoleTransport)({
|
|
54698
|
-
formatter: (0, import_strogger.createJsonFormatter)(),
|
|
54699
|
-
level: isDebugEnabled ? import_strogger.LogLevel.DEBUG : isDevelopment ? import_strogger.LogLevel.INFO : import_strogger.LogLevel.WARN,
|
|
54700
|
-
useColors: !isDevelopment
|
|
54701
|
-
})
|
|
54702
|
-
],
|
|
54784
|
+
transports: consoleTransport,
|
|
54703
54785
|
env: {
|
|
54704
54786
|
STAGE: isDevelopment ? "dev" : "prod",
|
|
54705
|
-
LOG_LEVEL: isDebugEnabled ? "DEBUG" : isDevelopment ? "INFO" : "
|
|
54787
|
+
LOG_LEVEL: isDebugEnabled ? "DEBUG" : isDevelopment ? "INFO" : "ERROR"
|
|
54706
54788
|
}
|
|
54707
54789
|
});
|
|
54708
54790
|
var createComponentLogger = (component) => ({
|
|
@@ -54729,25 +54811,6 @@ var memoizedServiceChecks = memoize(createAWSServiceChecks, {
|
|
|
54729
54811
|
// 10 minutes
|
|
54730
54812
|
maxSize: 10
|
|
54731
54813
|
});
|
|
54732
|
-
var getServiceCheckKeys = (serviceName) => {
|
|
54733
|
-
const serviceMapping = {
|
|
54734
|
-
"Lambda": ["lambdaEnvironmentVariables", "lambdaMemory"],
|
|
54735
|
-
"S3": ["s3Buckets", "s3IntelligentTiering"],
|
|
54736
|
-
"DynamoDB": ["dynamoDBAutoScaling", "dynamoDBStreams"],
|
|
54737
|
-
"RDS": ["rdsEncryption", "rdsMultiAZ"],
|
|
54738
|
-
"EC2": ["ec2InstanceType", "natGatewayUsage", "securityGroups", "ebsUnusedVolumes"],
|
|
54739
|
-
"IAM": ["iamPolicies"],
|
|
54740
|
-
"SNS": ["sns"],
|
|
54741
|
-
"SQS": ["sqs"],
|
|
54742
|
-
"StepFunctions": ["stepFunctions"],
|
|
54743
|
-
"CloudTrail": ["cloudTrailLogging"],
|
|
54744
|
-
"ApiGateway": ["apiGateway"],
|
|
54745
|
-
"SecretsManager": ["secretsManager"],
|
|
54746
|
-
"KMS": ["kmsKeys"],
|
|
54747
|
-
"EventBridge": ["eventBridgeRules"]
|
|
54748
|
-
};
|
|
54749
|
-
return serviceMapping[serviceName] || [serviceName];
|
|
54750
|
-
};
|
|
54751
54814
|
var createResourceFilter = (selectedServices) => {
|
|
54752
54815
|
if (selectedServices.includes("All services")) {
|
|
54753
54816
|
return (cloudFormationResource) => !cloudFormationResource.Type.startsWith("AWS::CDK::");
|
|
@@ -54764,13 +54827,16 @@ var createResourceFilter = (selectedServices) => {
|
|
|
54764
54827
|
};
|
|
54765
54828
|
var runStaticAnalysis = (cloudformationTemplate, createFinding2, selectedServices = [], solutionsRegistry = {}) => {
|
|
54766
54829
|
const serviceChecks = memoizedServiceChecks();
|
|
54767
|
-
const allServiceKeys = Object.keys(serviceChecks)
|
|
54768
|
-
const servicesToAnalyze = selectedServices.length > 0 && !selectedServices.includes("All services") ? selectedServices : allServiceKeys.filter(
|
|
54830
|
+
const allServiceKeys = Object.keys(serviceChecks).filter(
|
|
54769
54831
|
(serviceKey) => serviceKey !== "solutionsPatterns"
|
|
54770
54832
|
);
|
|
54771
|
-
const
|
|
54833
|
+
const { services: normalizedServices } = normalizeServiceSelection(selectedServices);
|
|
54834
|
+
const servicesToAnalyze = mapServicesToCheckKeys(
|
|
54835
|
+
normalizedServices,
|
|
54836
|
+
allServiceKeys
|
|
54837
|
+
);
|
|
54772
54838
|
const analysisFindings = {};
|
|
54773
|
-
const resourceFilter = createResourceFilter(
|
|
54839
|
+
const resourceFilter = createResourceFilter(normalizedServices);
|
|
54774
54840
|
const userResources = Object.entries(cloudformationTemplate.Resources || {}).filter(
|
|
54775
54841
|
([, cloudFormationResource]) => resourceFilter(cloudFormationResource)
|
|
54776
54842
|
).reduce(
|
|
@@ -54780,37 +54846,36 @@ var runStaticAnalysis = (cloudformationTemplate, createFinding2, selectedService
|
|
|
54780
54846
|
},
|
|
54781
54847
|
{}
|
|
54782
54848
|
);
|
|
54783
|
-
for (const
|
|
54784
|
-
|
|
54785
|
-
|
|
54786
|
-
|
|
54787
|
-
const
|
|
54788
|
-
|
|
54789
|
-
|
|
54790
|
-
analysisLogger.warn(
|
|
54791
|
-
`\u26A0\uFE0F Service check function for ${serviceName} is not available`
|
|
54792
|
-
);
|
|
54793
|
-
}
|
|
54794
|
-
continue;
|
|
54795
|
-
}
|
|
54796
|
-
const typedServiceCheckFunction = serviceCheckFunction;
|
|
54797
|
-
const serviceAnalysisResult = typedServiceCheckFunction(
|
|
54798
|
-
{ Resources: userResources },
|
|
54799
|
-
createFinding2
|
|
54849
|
+
for (const checkKey of servicesToAnalyze) {
|
|
54850
|
+
try {
|
|
54851
|
+
const serviceCheckFunction = serviceChecks[checkKey];
|
|
54852
|
+
if (typeof serviceCheckFunction !== "function") {
|
|
54853
|
+
const serviceLabel = getServiceLabelForCheckKey(checkKey) ?? checkKey;
|
|
54854
|
+
analysisLogger.warn(
|
|
54855
|
+
`\u26A0\uFE0F Service check function for ${serviceLabel} (${checkKey}) is not available`
|
|
54800
54856
|
);
|
|
54801
|
-
|
|
54802
|
-
serviceAnalysisResult
|
|
54803
|
-
)) {
|
|
54804
|
-
if (!analysisFindings[resourceName]) {
|
|
54805
|
-
analysisFindings[resourceName] = { issues: [] };
|
|
54806
|
-
}
|
|
54807
|
-
analysisFindings[resourceName].issues.push(...resourceFindings.issues);
|
|
54808
|
-
}
|
|
54809
|
-
} catch (analysisError) {
|
|
54810
|
-
analysisLogger.warn(`\u26A0\uFE0F Error in ${serviceName} analysis (${checkKey})`, {
|
|
54811
|
-
error: analysisError instanceof Error ? analysisError.message : String(analysisError)
|
|
54812
|
-
});
|
|
54857
|
+
continue;
|
|
54813
54858
|
}
|
|
54859
|
+
const serviceAnalysisResult = serviceCheckFunction(
|
|
54860
|
+
{ Resources: userResources },
|
|
54861
|
+
createFinding2
|
|
54862
|
+
);
|
|
54863
|
+
for (const [resourceName, resourceFindings] of Object.entries(
|
|
54864
|
+
serviceAnalysisResult
|
|
54865
|
+
)) {
|
|
54866
|
+
if (!analysisFindings[resourceName]) {
|
|
54867
|
+
analysisFindings[resourceName] = { issues: [] };
|
|
54868
|
+
}
|
|
54869
|
+
analysisFindings[resourceName].issues.push(...resourceFindings.issues);
|
|
54870
|
+
}
|
|
54871
|
+
} catch (analysisError) {
|
|
54872
|
+
const serviceLabel = getServiceLabelForCheckKey(checkKey) ?? checkKey;
|
|
54873
|
+
analysisLogger.warn(
|
|
54874
|
+
`\u26A0\uFE0F Error in ${serviceLabel} analysis (${checkKey})`,
|
|
54875
|
+
{
|
|
54876
|
+
error: analysisError instanceof Error ? analysisError.message : String(analysisError)
|
|
54877
|
+
}
|
|
54878
|
+
);
|
|
54814
54879
|
}
|
|
54815
54880
|
}
|
|
54816
54881
|
if (Object.keys(solutionsRegistry).length > 0) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ConstructMetadata } from '../analysis/static/solutionConstructs/loadConstructMetadata';
|
|
2
2
|
import type { AWSServiceChecks } from '../functions/factories/awsServices';
|
|
3
|
-
export type
|
|
3
|
+
export type ServiceCheckKey = Exclude<keyof AWSServiceChecks, 'solutionsPatterns'>;
|
|
4
|
+
export type SpecificServiceName = 'IAM' | 'S3' | 'Lambda' | 'DynamoDB' | 'RDS' | 'EC2' | 'SNS' | 'SQS' | 'StepFunctions' | 'CloudTrail' | 'ApiGateway' | 'SecretsManager' | 'KMS' | 'EventBridge';
|
|
5
|
+
export type ServiceName = 'All services' | SpecificServiceName;
|
|
4
6
|
export type RunAnalysisTypes = {
|
|
5
7
|
stacks: Record<string, CloudFormationStack>;
|
|
6
8
|
inlineFindings: Issue[];
|