@contrast/contrast 1.0.0 → 1.0.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/.prettierignore +3 -0
- package/README.md +115 -78
- package/dist/audit/AnalysisEngine.js +37 -0
- package/dist/audit/catalogueApplication/catalogueApplication.js +36 -0
- package/dist/audit/dotnetAnalysisEngine/index.js +25 -0
- package/dist/audit/dotnetAnalysisEngine/parseLockFileContents.js +35 -0
- package/dist/audit/dotnetAnalysisEngine/parseProjectFileContents.js +15 -0
- package/dist/audit/dotnetAnalysisEngine/readLockFileContents.js +18 -0
- package/dist/audit/dotnetAnalysisEngine/readProjectFileContents.js +14 -0
- package/dist/audit/dotnetAnalysisEngine/sanitizer.js +9 -0
- package/dist/audit/goAnalysisEngine/index.js +17 -0
- package/dist/audit/goAnalysisEngine/parseProjectFileContents.js +164 -0
- package/dist/audit/goAnalysisEngine/readProjectFileContents.js +21 -0
- package/dist/audit/goAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/javaAnalysisEngine/index.js +34 -0
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +153 -0
- package/dist/audit/javaAnalysisEngine/parseProjectFileContents.js +353 -0
- package/dist/audit/javaAnalysisEngine/readProjectFileContents.js +98 -0
- package/dist/audit/javaAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +24 -0
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +24 -0
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +35 -0
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +23 -0
- package/dist/audit/languageAnalysisEngine/commonApi.js +18 -0
- package/dist/audit/languageAnalysisEngine/constants.js +20 -0
- package/dist/audit/languageAnalysisEngine/filterProjectPath.js +20 -0
- package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +25 -0
- package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +39 -0
- package/dist/audit/languageAnalysisEngine/index.js +39 -0
- package/dist/audit/languageAnalysisEngine/langugageAnalysisFactory.js +95 -0
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +121 -0
- package/dist/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +17 -0
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +257 -0
- package/dist/audit/languageAnalysisEngine/report/newReportingFeature.js +81 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +133 -0
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +41 -0
- package/dist/audit/languageAnalysisEngine/util/capabilities.js +11 -0
- package/dist/audit/languageAnalysisEngine/util/generalAPI.js +39 -0
- package/dist/audit/languageAnalysisEngine/util/requestUtils.js +14 -0
- package/dist/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +40 -0
- package/dist/audit/nodeAnalysisEngine/index.js +31 -0
- package/dist/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +18 -0
- package/dist/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +51 -0
- package/dist/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +18 -0
- package/dist/audit/nodeAnalysisEngine/readNPMLockFileContents.js +17 -0
- package/dist/audit/nodeAnalysisEngine/readProjectFileContents.js +14 -0
- package/dist/audit/nodeAnalysisEngine/readYarnLockFileContents.js +24 -0
- package/dist/audit/nodeAnalysisEngine/sanitizer.js +9 -0
- package/dist/audit/phpAnalysisEngine/index.js +23 -0
- package/dist/audit/phpAnalysisEngine/parseLockFileContents.js +52 -0
- package/dist/audit/phpAnalysisEngine/readLockFileContents.js +13 -0
- package/dist/audit/phpAnalysisEngine/readProjectFileContents.js +16 -0
- package/dist/audit/phpAnalysisEngine/sanitizer.js +5 -0
- package/dist/audit/pythonAnalysisEngine/index.js +25 -0
- package/dist/audit/pythonAnalysisEngine/parsePipfileLockContents.js +17 -0
- package/dist/audit/pythonAnalysisEngine/parseProjectFileContents.js +21 -0
- package/dist/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +13 -0
- package/dist/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +14 -0
- package/dist/audit/pythonAnalysisEngine/sanitizer.js +7 -0
- package/dist/audit/rubyAnalysisEngine/index.js +25 -0
- package/dist/audit/rubyAnalysisEngine/parseGemfileLockContents.js +176 -0
- package/dist/audit/rubyAnalysisEngine/parsedGemfile.js +22 -0
- package/dist/audit/rubyAnalysisEngine/readGemfileContents.js +14 -0
- package/dist/audit/rubyAnalysisEngine/readGemfileLockContents.js +14 -0
- package/dist/audit/rubyAnalysisEngine/sanitizer.js +6 -0
- package/dist/commands/audit/auditConfig.js +25 -0
- package/dist/commands/audit/auditController.js +31 -0
- package/dist/commands/audit/help.js +52 -0
- package/dist/commands/audit/processAudit.js +18 -0
- package/dist/commands/audit/saveFile.js +11 -0
- package/dist/commands/auth/auth.js +20 -2
- package/dist/commands/config/config.js +19 -8
- package/dist/commands/scan/processScan.js +9 -13
- package/dist/common/HTTPClient.js +112 -13
- package/dist/common/errorHandling.js +65 -1
- package/dist/common/versionChecker.js +30 -0
- package/dist/constants/constants.js +4 -2
- package/dist/constants/lambda.js +32 -4
- package/dist/constants/locales.js +60 -21
- package/dist/constants.js +181 -21
- package/dist/index.js +50 -23
- package/dist/lambda/aws.js +14 -11
- package/dist/lambda/help.js +4 -0
- package/dist/lambda/lambda.js +50 -27
- package/dist/lambda/lambdaUtils.js +72 -0
- package/dist/lambda/logUtils.js +11 -1
- package/dist/lambda/scanDetailCompletion.js +4 -4
- package/dist/lambda/scanRequest.js +11 -5
- package/dist/lambda/utils.js +110 -53
- package/dist/sbom/generateSbom.js +20 -0
- package/dist/scan/autoDetection.js +0 -32
- package/dist/scan/fileUtils.js +1 -1
- package/dist/scan/help.js +14 -40
- package/dist/scan/populateProjectIdAndProjectName.js +5 -0
- package/dist/scan/saveResults.js +14 -0
- package/dist/scan/scan.js +105 -40
- package/dist/scan/scanConfig.js +39 -0
- package/dist/scan/scanController.js +19 -16
- package/dist/scan/scanResults.js +24 -16
- package/dist/utils/commonApi.js +3 -3
- package/dist/utils/paramsUtil/commandlineParams.js +1 -20
- package/dist/utils/paramsUtil/paramHandler.js +3 -6
- package/dist/utils/parsedCLIOptions.js +14 -8
- package/dist/utils/requestUtils.js +1 -1
- package/dist/utils/saveFile.js +19 -0
- package/package.json +26 -21
- package/src/audit/AnalysisEngine.js +103 -0
- package/src/audit/catalogueApplication/catalogueApplication.js +42 -0
- package/src/audit/dotnetAnalysisEngine/index.js +26 -0
- package/src/audit/dotnetAnalysisEngine/parseLockFileContents.js +47 -0
- package/src/audit/dotnetAnalysisEngine/parseProjectFileContents.js +29 -0
- package/src/audit/dotnetAnalysisEngine/readLockFileContents.js +30 -0
- package/src/audit/dotnetAnalysisEngine/readProjectFileContents.js +26 -0
- package/src/audit/dotnetAnalysisEngine/sanitizer.js +11 -0
- package/src/audit/goAnalysisEngine/index.js +18 -0
- package/src/audit/goAnalysisEngine/parseProjectFileContents.js +209 -0
- package/src/audit/goAnalysisEngine/readProjectFileContents.js +31 -0
- package/src/audit/goAnalysisEngine/sanitizer.js +7 -0
- package/src/audit/javaAnalysisEngine/index.js +41 -0
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +222 -0
- package/src/audit/javaAnalysisEngine/parseProjectFileContents.js +420 -0
- package/src/audit/javaAnalysisEngine/readProjectFileContents.js +141 -0
- package/src/audit/javaAnalysisEngine/sanitizer.js +6 -0
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +35 -0
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +41 -0
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasLockFile.js +54 -0
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +32 -0
- package/src/audit/languageAnalysisEngine/commonApi.js +20 -0
- package/src/audit/languageAnalysisEngine/constants.js +23 -0
- package/src/audit/languageAnalysisEngine/filterProjectPath.js +21 -0
- package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +41 -0
- package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +72 -0
- package/src/audit/languageAnalysisEngine/index.js +45 -0
- package/src/audit/languageAnalysisEngine/langugageAnalysisFactory.js +126 -0
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +177 -0
- package/src/audit/languageAnalysisEngine/report/checkIgnoreDevDep.js +27 -0
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.js +303 -0
- package/src/audit/languageAnalysisEngine/report/newReportingFeature.js +124 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.js +190 -0
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +51 -0
- package/src/audit/languageAnalysisEngine/util/capabilities.js +12 -0
- package/src/audit/languageAnalysisEngine/util/generalAPI.js +43 -0
- package/src/audit/languageAnalysisEngine/util/requestUtils.js +17 -0
- package/src/audit/nodeAnalysisEngine/handleNPMLockFileV2.js +49 -0
- package/src/audit/nodeAnalysisEngine/index.js +35 -0
- package/src/audit/nodeAnalysisEngine/parseNPMLockFileContents.js +20 -0
- package/src/audit/nodeAnalysisEngine/parseYarn2LockFileContents.js +63 -0
- package/src/audit/nodeAnalysisEngine/parseYarnLockFileContents.js +26 -0
- package/src/audit/nodeAnalysisEngine/readNPMLockFileContents.js +23 -0
- package/src/audit/nodeAnalysisEngine/readProjectFileContents.js +27 -0
- package/src/audit/nodeAnalysisEngine/readYarnLockFileContents.js +36 -0
- package/src/audit/nodeAnalysisEngine/sanitizer.js +11 -0
- package/src/audit/phpAnalysisEngine/index.js +27 -0
- package/src/audit/phpAnalysisEngine/parseLockFileContents.js +60 -0
- package/src/audit/phpAnalysisEngine/readLockFileContents.js +14 -0
- package/src/audit/phpAnalysisEngine/readProjectFileContents.js +25 -0
- package/src/audit/phpAnalysisEngine/sanitizer.js +4 -0
- package/src/audit/pythonAnalysisEngine/index.js +55 -0
- package/src/audit/pythonAnalysisEngine/parsePipfileLockContents.js +23 -0
- package/src/audit/pythonAnalysisEngine/parseProjectFileContents.js +33 -0
- package/src/audit/pythonAnalysisEngine/readPipfileLockFileContents.js +16 -0
- package/src/audit/pythonAnalysisEngine/readPythonProjectFileContents.js +22 -0
- package/src/audit/pythonAnalysisEngine/sanitizer.js +9 -0
- package/src/audit/rubyAnalysisEngine/index.js +30 -0
- package/src/audit/rubyAnalysisEngine/parseGemfileLockContents.js +215 -0
- package/src/audit/rubyAnalysisEngine/parsedGemfile.js +39 -0
- package/src/audit/rubyAnalysisEngine/readGemfileContents.js +18 -0
- package/src/audit/rubyAnalysisEngine/readGemfileLockContents.js +17 -0
- package/src/audit/rubyAnalysisEngine/sanitizer.js +8 -0
- package/src/commands/audit/auditConfig.ts +30 -0
- package/src/commands/audit/auditController.ts +31 -0
- package/src/commands/audit/help.ts +48 -0
- package/src/commands/audit/processAudit.ts +18 -0
- package/src/commands/audit/saveFile.ts +6 -0
- package/src/commands/auth/auth.js +26 -2
- package/src/commands/config/config.js +22 -8
- package/src/commands/scan/processScan.js +9 -13
- package/src/common/HTTPClient.js +149 -14
- package/src/common/errorHandling.ts +85 -2
- package/src/common/versionChecker.ts +39 -0
- package/src/constants/constants.js +5 -4
- package/src/constants/lambda.js +45 -4
- package/src/constants/locales.js +76 -26
- package/src/constants.js +204 -23
- package/src/index.ts +67 -27
- package/src/lambda/aws.ts +13 -12
- package/src/lambda/help.ts +4 -0
- package/src/lambda/lambda.ts +53 -34
- package/src/lambda/lambdaUtils.ts +111 -0
- package/src/lambda/logUtils.ts +19 -1
- package/src/lambda/scanDetailCompletion.ts +4 -4
- package/src/lambda/scanRequest.ts +13 -11
- package/src/lambda/utils.ts +149 -81
- package/src/sbom/generateSbom.ts +17 -0
- package/src/scan/autoDetection.js +0 -29
- package/src/scan/fileUtils.js +1 -1
- package/src/scan/help.js +14 -45
- package/src/scan/populateProjectIdAndProjectName.js +5 -0
- package/src/scan/saveResults.js +14 -0
- package/src/scan/scan.js +127 -58
- package/src/scan/scanConfig.js +54 -0
- package/src/scan/scanController.js +22 -15
- package/src/scan/scanResults.js +32 -19
- package/src/utils/commonApi.js +2 -3
- package/src/utils/getConfig.ts +2 -0
- package/src/utils/paramsUtil/commandlineParams.js +1 -26
- package/src/utils/paramsUtil/paramHandler.js +3 -7
- package/src/utils/parsedCLIOptions.js +11 -9
- package/src/utils/requestUtils.js +1 -1
- package/src/utils/saveFile.js +19 -0
- package/dist/lambda/scanDetail.js +0 -30
- package/dist/scan/fileFinder.js +0 -15
- package/dist/utils/paramsUtil/yamlParams.js +0 -6
package/src/lambda/aws.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import i18n from 'i18n'
|
|
1
2
|
import {
|
|
2
3
|
Lambda,
|
|
3
4
|
GetFunctionCommand,
|
|
@@ -44,12 +45,9 @@ const getLambdaClient = (lambdaOptions: LambdaOptions) => {
|
|
|
44
45
|
const clientOptions = getAwsClientOptions(lambdaOptions)
|
|
45
46
|
return new Lambda(clientOptions)
|
|
46
47
|
} catch (error) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
throw error
|
|
48
|
+
throw new CliError(ERRORS.AWS_ERROR, {
|
|
49
|
+
description: (error as Error).message
|
|
50
|
+
})
|
|
53
51
|
}
|
|
54
52
|
}
|
|
55
53
|
|
|
@@ -89,7 +87,9 @@ const getLayersLinks = async (
|
|
|
89
87
|
}
|
|
90
88
|
} catch (e) {
|
|
91
89
|
if (e instanceof ResourceNotFoundException) {
|
|
92
|
-
e.message =
|
|
90
|
+
e.message = i18n.__('layerNotFound', {
|
|
91
|
+
layerArn: layerDict.Arn || 'unknown_arn'
|
|
92
|
+
})
|
|
93
93
|
throw e
|
|
94
94
|
}
|
|
95
95
|
throw e
|
|
@@ -190,10 +190,10 @@ const getAttachedPolicies = async (roleName: string, client: IAMClient) => {
|
|
|
190
190
|
)
|
|
191
191
|
const attachedPoliciesPromises = listAttachedPolicies.map(
|
|
192
192
|
async (policyDict: { PolicyArn: any; PolicyName: any }) => {
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
})
|
|
193
|
+
const { PolicyArn, PolicyName } = policyDict
|
|
194
|
+
const getPolicyCommand = new GetPolicyCommand({ PolicyArn })
|
|
196
195
|
const policy = await client.send(getPolicyCommand)
|
|
196
|
+
|
|
197
197
|
if (policy.Policy) {
|
|
198
198
|
const getPolicyVersionCommand = new GetPolicyVersionCommand({
|
|
199
199
|
PolicyArn: policy.Policy.Arn,
|
|
@@ -203,8 +203,9 @@ const getAttachedPolicies = async (roleName: string, client: IAMClient) => {
|
|
|
203
203
|
const policyDoc = JSON.parse(
|
|
204
204
|
decodeURIComponent(policyVersion?.PolicyVersion?.Document || '{}')
|
|
205
205
|
)
|
|
206
|
-
|
|
207
|
-
policyDoc['
|
|
206
|
+
|
|
207
|
+
policyDoc['PolicyName'] = PolicyName
|
|
208
|
+
policyDoc['PolicyArn'] = PolicyArn
|
|
208
209
|
return policyDoc
|
|
209
210
|
}
|
|
210
211
|
}
|
package/src/lambda/help.ts
CHANGED
|
@@ -21,6 +21,10 @@ const lambdaUsageGuide = commandLineUsage([
|
|
|
21
21
|
name: i18n.__('lambdaFunctionNameOption'),
|
|
22
22
|
summary: i18n.__('lambdaFunctionNameSummery')
|
|
23
23
|
},
|
|
24
|
+
{
|
|
25
|
+
name: i18n.__('lambdaListFunctionsOption'),
|
|
26
|
+
summary: i18n.__('lambdaListFunctionsSummery')
|
|
27
|
+
},
|
|
24
28
|
{
|
|
25
29
|
name: i18n.__('lambdaEndpointOption'),
|
|
26
30
|
summary:
|
package/src/lambda/lambda.ts
CHANGED
|
@@ -10,10 +10,12 @@ import { log } from './logUtils'
|
|
|
10
10
|
import { pollScanUntilCompletion } from './scanDetailCompletion'
|
|
11
11
|
import { requestScanFunctionPost } from './scanRequest'
|
|
12
12
|
import { getScanResults } from './scanResults'
|
|
13
|
-
import {
|
|
13
|
+
import { printResults } from './utils'
|
|
14
|
+
import { getAllLambdas, printAvailableLambdas } from './lambdaUtils'
|
|
14
15
|
|
|
15
16
|
type LambdaOptions = {
|
|
16
17
|
functionName?: string
|
|
18
|
+
listFunctions?: boolean
|
|
17
19
|
region?: string
|
|
18
20
|
endpointUrl?: string
|
|
19
21
|
profile?: string
|
|
@@ -42,38 +44,49 @@ const printHelpMessage = () => {
|
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
const getLambdaOptions = (argv: string[]) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
try {
|
|
48
|
+
const lambdaDefinitions = [
|
|
49
|
+
{ name: 'function-name', alias: 'f', type: String },
|
|
50
|
+
{ name: 'list-functions', alias: 'l', type: Boolean },
|
|
51
|
+
{ name: 'region', alias: 'r', type: String },
|
|
52
|
+
{ name: 'endpoint-url', alias: 'e', type: String },
|
|
53
|
+
{ name: 'profile', alias: 'p', type: String },
|
|
54
|
+
{ name: 'help', alias: 'h', type: Boolean },
|
|
55
|
+
{ name: 'verbose', alias: 'v', type: Boolean },
|
|
56
|
+
{ name: 'json-output', alias: 'j', type: Boolean }
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
const lambdaOptions: LambdaOptions = commandLineArgs(lambdaDefinitions, {
|
|
60
|
+
argv,
|
|
61
|
+
partial: true,
|
|
62
|
+
camelCase: true,
|
|
63
|
+
caseInsensitive: true
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
return lambdaOptions
|
|
67
|
+
} catch (error) {
|
|
68
|
+
throw new CliError(ERRORS.VALIDATION_FAILED, {
|
|
69
|
+
description: (error as Error).message
|
|
70
|
+
})
|
|
71
|
+
}
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
const processLambda = async (argv: string[]) => {
|
|
66
|
-
|
|
67
|
-
|
|
75
|
+
try {
|
|
76
|
+
const lambdaOptions = getLambdaOptions(argv)
|
|
77
|
+
const { help } = lambdaOptions
|
|
68
78
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
if (help) {
|
|
80
|
+
return handleLambdaHelp()
|
|
81
|
+
}
|
|
72
82
|
|
|
73
|
-
try {
|
|
74
83
|
validateRequiredLambdaParams(lambdaOptions)
|
|
75
84
|
|
|
76
|
-
|
|
85
|
+
if (lambdaOptions.listFunctions) {
|
|
86
|
+
await getAvailableFunctions(lambdaOptions)
|
|
87
|
+
} else {
|
|
88
|
+
await actualProcessLambda(lambdaOptions)
|
|
89
|
+
}
|
|
77
90
|
} catch (error) {
|
|
78
91
|
if (error instanceof CliError) {
|
|
79
92
|
console.error(error.getErrorMessage())
|
|
@@ -84,6 +97,11 @@ const processLambda = async (argv: string[]) => {
|
|
|
84
97
|
}
|
|
85
98
|
}
|
|
86
99
|
|
|
100
|
+
const getAvailableFunctions = async (lambdaOptions: LambdaOptions) => {
|
|
101
|
+
const lambdas = await getAllLambdas(lambdaOptions)
|
|
102
|
+
printAvailableLambdas(lambdas, { runtimes: ['python', 'java'] })
|
|
103
|
+
}
|
|
104
|
+
|
|
87
105
|
const actualProcessLambda = async (lambdaOptions: LambdaOptions) => {
|
|
88
106
|
const auth = getAuth()
|
|
89
107
|
const startTime = performance.now()
|
|
@@ -134,18 +152,20 @@ const actualProcessLambda = async (lambdaOptions: LambdaOptions) => {
|
|
|
134
152
|
log(`----- Scan completed ${(scanDurationMs / 1000).toFixed(2)}s -----`)
|
|
135
153
|
|
|
136
154
|
if (results?.length) {
|
|
137
|
-
|
|
155
|
+
printResults(results)
|
|
138
156
|
}
|
|
139
157
|
}
|
|
140
158
|
|
|
141
159
|
const validateRequiredLambdaParams = (options: LambdaOptions) => {
|
|
142
160
|
if (options._unknown?.length) {
|
|
143
161
|
throw new CliError(ERRORS.VALIDATION_FAILED, {
|
|
144
|
-
description: i18n.__('notSupportedFlags',
|
|
162
|
+
description: i18n.__('notSupportedFlags', {
|
|
163
|
+
flags: options._unknown.join('\n')
|
|
164
|
+
})
|
|
145
165
|
})
|
|
146
166
|
}
|
|
147
167
|
|
|
148
|
-
if (!options?.functionName) {
|
|
168
|
+
if (!options?.functionName && !options?.listFunctions) {
|
|
149
169
|
throw new CliError(ERRORS.VALIDATION_FAILED, {
|
|
150
170
|
errorCode: 'missingFunctionName'
|
|
151
171
|
})
|
|
@@ -158,10 +178,9 @@ const validateRequiredLambdaParams = (options: LambdaOptions) => {
|
|
|
158
178
|
|
|
159
179
|
if (flagsWithoutValues.length) {
|
|
160
180
|
throw new CliError(ERRORS.VALIDATION_FAILED, {
|
|
161
|
-
description: i18n.__(
|
|
162
|
-
'
|
|
163
|
-
|
|
164
|
-
)
|
|
181
|
+
description: i18n.__('missingFlagArguments', {
|
|
182
|
+
flags: flagsWithoutValues.join('\n')
|
|
183
|
+
})
|
|
165
184
|
})
|
|
166
185
|
}
|
|
167
186
|
}
|
|
@@ -171,4 +190,4 @@ const handleLambdaHelp = () => {
|
|
|
171
190
|
process.exit(0)
|
|
172
191
|
}
|
|
173
192
|
|
|
174
|
-
export { processLambda, LambdaOptions, ApiParams }
|
|
193
|
+
export { processLambda, LambdaOptions, ApiParams, getAvailableFunctions }
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import logSymbols from 'log-symbols'
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
import i18n from 'i18n'
|
|
4
|
+
import {
|
|
5
|
+
FunctionConfiguration,
|
|
6
|
+
ListFunctionsCommand
|
|
7
|
+
} from '@aws-sdk/client-lambda'
|
|
8
|
+
import { groupBy, sortBy } from 'lodash'
|
|
9
|
+
import { getLambdaClient } from './aws'
|
|
10
|
+
import ora from '../utils/oraWrapper'
|
|
11
|
+
import { LambdaOptions } from './lambda'
|
|
12
|
+
import { log, getReadableFileSize } from './logUtils'
|
|
13
|
+
|
|
14
|
+
type RuntimeLanguage = 'java' | 'python'
|
|
15
|
+
|
|
16
|
+
type FilterLambdas = {
|
|
17
|
+
runtimes: RuntimeLanguage[]
|
|
18
|
+
filterText?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @param fucntions all user lambdas
|
|
24
|
+
* @param options filter values: runtime / free text
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
const printAvailableLambdas = (
|
|
28
|
+
fucntions: FunctionConfiguration[] = [],
|
|
29
|
+
options: FilterLambdas
|
|
30
|
+
) => {
|
|
31
|
+
const { runtimes, filterText = '' } = options
|
|
32
|
+
const searchValue = filterText?.trim().toLowerCase()
|
|
33
|
+
|
|
34
|
+
const filteredFunctions = fucntions
|
|
35
|
+
.filter(f => runtimes.some(r => f.Runtime?.includes(r)))
|
|
36
|
+
.filter(f => f.FunctionName?.toLowerCase().includes(searchValue))
|
|
37
|
+
log(
|
|
38
|
+
i18n.__('availableForScan', {
|
|
39
|
+
icon: logSymbols.success,
|
|
40
|
+
count: `${filteredFunctions.length}`
|
|
41
|
+
})
|
|
42
|
+
)
|
|
43
|
+
const groupByRuntime = groupBy(filteredFunctions, 'Runtime')
|
|
44
|
+
|
|
45
|
+
Object.entries(groupByRuntime).forEach(([runtime, arr]) => {
|
|
46
|
+
const sorted = sortBy(arr, 'FunctionName')
|
|
47
|
+
const count = `${arr.filter(a => a.Runtime === runtime).length}`
|
|
48
|
+
|
|
49
|
+
log(chalk.gray(i18n.__('runtimeCount', { runtime, count })))
|
|
50
|
+
sorted.forEach(f => {
|
|
51
|
+
const size = f.CodeSize ? getReadableFileSize(f.CodeSize) : ''
|
|
52
|
+
log(`${f.FunctionName} ${chalk.gray(`(${size})`)}`)
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
*
|
|
59
|
+
* @param lambdaOptions to create lambdaClient
|
|
60
|
+
* @returns list of all user lambdas that availbale to scan
|
|
61
|
+
*/
|
|
62
|
+
const getAllLambdas = async (lambdaOptions: LambdaOptions) => {
|
|
63
|
+
const functions: FunctionConfiguration[] = []
|
|
64
|
+
const spinner = ora.returnOra(i18n.__('loadingFunctionList'))
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const client = getLambdaClient(lambdaOptions)
|
|
68
|
+
const command = new ListFunctionsCommand({})
|
|
69
|
+
|
|
70
|
+
ora.startSpinner(spinner)
|
|
71
|
+
|
|
72
|
+
const data = await client.send(command)
|
|
73
|
+
const { Functions } = data
|
|
74
|
+
let { NextMarker } = data
|
|
75
|
+
|
|
76
|
+
if (!Functions?.length) {
|
|
77
|
+
ora.failSpinner(spinner, i18n.__('noFunctionsFound'))
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
functions.push(...Functions)
|
|
82
|
+
spinner.text = i18n.__('functionsFound', { count: `${functions.length}` })
|
|
83
|
+
|
|
84
|
+
// pagination on functions
|
|
85
|
+
while (NextMarker) {
|
|
86
|
+
command.input.Marker = NextMarker
|
|
87
|
+
const chank = await client.send(command)
|
|
88
|
+
|
|
89
|
+
if (chank.Functions?.length) {
|
|
90
|
+
functions.push(...chank.Functions)
|
|
91
|
+
spinner.text = i18n.__('functionsFound', {
|
|
92
|
+
count: `${functions.length}`
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
NextMarker = chank.NextMarker
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
ora.succeedSpinner(
|
|
100
|
+
spinner,
|
|
101
|
+
i18n.__('functionsFound', { count: `${functions.length}` })
|
|
102
|
+
)
|
|
103
|
+
} catch (error) {
|
|
104
|
+
ora.failSpinner(spinner, i18n.__('failedToLoadFunctions'))
|
|
105
|
+
throw error
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return functions
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export { getAllLambdas, printAvailableLambdas }
|
package/src/lambda/logUtils.ts
CHANGED
|
@@ -43,4 +43,22 @@ const prettyPrintJson = (obj: string | any, depth: number | null = null) => {
|
|
|
43
43
|
console.log(util.inspect(objToPrint, { colors: true, depth }))
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
* @param fileSizeInBytes
|
|
49
|
+
*
|
|
50
|
+
* @returns human readable format
|
|
51
|
+
*/
|
|
52
|
+
const getReadableFileSize = (fileSizeInBytes: number) => {
|
|
53
|
+
let i = -1
|
|
54
|
+
const byteUnits = [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB']
|
|
55
|
+
|
|
56
|
+
do {
|
|
57
|
+
fileSizeInBytes = fileSizeInBytes / 1024
|
|
58
|
+
i++
|
|
59
|
+
} while (fileSizeInBytes > 1024)
|
|
60
|
+
|
|
61
|
+
return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { log, prettyPrintJson, getReadableFileSize }
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import i18n from 'i18n'
|
|
1
2
|
import { sleep } from '../utils/requestUtils'
|
|
2
3
|
import { getHttpClient } from '../utils/commonApi'
|
|
3
4
|
import { ApiParams } from './lambda'
|
|
@@ -35,9 +36,8 @@ const pollScanUntilCompletion = async (
|
|
|
35
36
|
const client = getHttpClient(config)
|
|
36
37
|
|
|
37
38
|
const activeStatuses = ['PENDING', 'SCANNING', 'QUEUED']
|
|
38
|
-
const startedText = 'Scan started'
|
|
39
39
|
const maxEndTime = new Date().getTime() + timeoutInMinutes * MS_IN_MINUTE
|
|
40
|
-
const startScanSpinner = ora.returnOra(
|
|
40
|
+
const startScanSpinner = ora.returnOra(i18n.__('scanStarted'))
|
|
41
41
|
ora.startSpinner(startScanSpinner)
|
|
42
42
|
|
|
43
43
|
await sleep(5000) // wait 5 sec before first polling
|
|
@@ -62,12 +62,12 @@ const pollScanUntilCompletion = async (
|
|
|
62
62
|
|
|
63
63
|
await sleep(2 * 1000)
|
|
64
64
|
} catch (error) {
|
|
65
|
-
ora.failSpinner(startScanSpinner, '
|
|
65
|
+
ora.failSpinner(startScanSpinner, i18n.__('scanFailed'))
|
|
66
66
|
throw error
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
if (Date.now() >= maxEndTime) {
|
|
70
|
-
ora.failSpinner(startScanSpinner, '
|
|
70
|
+
ora.failSpinner(startScanSpinner, i18n.__('scanTimedOut'))
|
|
71
71
|
throw new CliError(ERRORS.FAILED_TO_GET_SCAN, {
|
|
72
72
|
errorCode: 'waitingTimedOut'
|
|
73
73
|
})
|
|
@@ -24,8 +24,7 @@ const sendScanPostRequest = async (
|
|
|
24
24
|
const client = getHttpClient(config)
|
|
25
25
|
|
|
26
26
|
if (showProgress) {
|
|
27
|
-
|
|
28
|
-
log(`${logSymbols.success} Sending Lambda Function scan request to Contrast`)
|
|
27
|
+
log(i18n.__('sendingScanRequest', { icon: logSymbols.success }))
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
const res = await client.postFunctionScan(config, params, functionsEvent)
|
|
@@ -33,7 +32,7 @@ const sendScanPostRequest = async (
|
|
|
33
32
|
|
|
34
33
|
if (statusCode === 201) {
|
|
35
34
|
if (showProgress) {
|
|
36
|
-
log(
|
|
35
|
+
log(i18n.__('scanRequestedSuccessfully', { icon: logSymbols.success }))
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
return body?.data?.scanId
|
|
@@ -45,11 +44,10 @@ const sendScanPostRequest = async (
|
|
|
45
44
|
let description = ''
|
|
46
45
|
switch (errorCode) {
|
|
47
46
|
case 'not_supported_runtime':
|
|
48
|
-
description = i18n.__(
|
|
49
|
-
|
|
50
|
-
data?.
|
|
51
|
-
|
|
52
|
-
)
|
|
47
|
+
description = i18n.__(errorCode, {
|
|
48
|
+
runtime: data?.runtime,
|
|
49
|
+
supportedRuntimes: data?.supportedRuntimes.sort().join(' | ')
|
|
50
|
+
})
|
|
53
51
|
errorCode = false
|
|
54
52
|
break
|
|
55
53
|
}
|
|
@@ -88,8 +86,12 @@ const requestScanFunctionPost = async (
|
|
|
88
86
|
const lambdaClient = getLambdaClient(lambdaOptions)
|
|
89
87
|
|
|
90
88
|
if (!jsonOutput) {
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
log(
|
|
90
|
+
i18n.__('fetchingConfiguration', {
|
|
91
|
+
icon: logSymbols.success,
|
|
92
|
+
functionName: chalk.bold(functionName)
|
|
93
|
+
})
|
|
94
|
+
)
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
const lambdaConfig = await getLambdaFunctionConfiguration(
|
|
@@ -125,7 +127,7 @@ const requestScanFunctionPost = async (
|
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
if (verbose) {
|
|
128
|
-
log(
|
|
130
|
+
log(i18n.__('fetchedConfiguration', { icon: logSymbols.success }))
|
|
129
131
|
prettyPrintJson(functionEvent)
|
|
130
132
|
}
|
|
131
133
|
|