1
1
import * as fs from 'fs' ;
2
- import * as YAML from 'js-yaml' ;
3
2
import { isLocalFolder } from '../../../../lib/detect' ;
4
3
import { getFileType } from '../../../../lib/iac/iac-parser' ;
5
4
import * as util from 'util' ;
6
5
import { IacFileTypes } from '../../../../lib/iac/constants' ;
7
6
import { IacFileScanResult , IacFileMetadata , IacFileData } from './types' ;
8
- import { buildPolicyEngine } from './policy-engine' ;
7
+ import { getPolicyEngine } from './policy-engine' ;
9
8
import { formatResults } from './results-formatter' ;
9
+ import { tryParseIacFile } from './parsers' ;
10
+ import { isLocalCacheExists , REQUIRED_LOCAL_CACHE_FILES } from './local-cache' ;
10
11
11
12
const readFileContentsAsync = util . promisify ( fs . readFile ) ;
12
- const REQUIRED_K8S_FIELDS = [ 'apiVersion' , 'kind' , 'metadata' ] ;
13
13
14
14
// this method executes the local processing engine and then formats the results to adapt with the CLI output.
15
15
// the current version is dependent on files to be present locally which are not part of the source code.
16
16
// without these files this method would fail.
17
17
// if you're interested in trying out the experimental local execution model for IaC scanning, please reach-out.
18
18
export async function test ( pathToScan : string , options ) {
19
+ if ( ! isLocalCacheExists ( ) )
20
+ throw Error (
21
+ `Missing IaC local cache data, please validate you have: \n${ REQUIRED_LOCAL_CACHE_FILES . join (
22
+ '\n' ,
23
+ ) } `,
24
+ ) ;
19
25
// TODO: add support for proper typing of old TestResult interface.
20
26
const results = await localProcessing ( pathToScan ) ;
21
27
const formattedResults = formatResults ( results , options ) ;
@@ -27,12 +33,9 @@ export async function test(pathToScan: string, options) {
27
33
async function localProcessing (
28
34
pathToScan : string ,
29
35
) : Promise < IacFileScanResult [ ] > {
30
- const policyEngine = await buildPolicyEngine ( ) ;
31
36
const filePathsToScan = await getFilePathsToScan ( pathToScan ) ;
32
- const fileDataToScan = await parseFileContentsForPolicyEngine (
33
- filePathsToScan ,
34
- ) ;
35
- const scanResults = await policyEngine . scanFiles ( fileDataToScan ) ;
37
+ const fileDataToScan = await parseFilesForScan ( filePathsToScan ) ;
38
+ const scanResults = await scanFilesForIssues ( fileDataToScan ) ;
36
39
return scanResults ;
37
40
}
38
41
@@ -42,18 +45,13 @@ async function getFilePathsToScan(pathToScan): Promise<IacFileMetadata[]> {
42
45
'IaC Experimental version does not support directory scan yet.' ,
43
46
) ;
44
47
}
45
- if ( getFileType ( pathToScan ) === 'tf' ) {
46
- throw new Error (
47
- 'IaC Experimental version does not support Terraform scan yet.' ,
48
- ) ;
49
- }
50
48
51
49
return [
52
50
{ filePath : pathToScan , fileType : getFileType ( pathToScan ) as IacFileTypes } ,
53
51
] ;
54
52
}
55
53
56
- async function parseFileContentsForPolicyEngine (
54
+ async function parseFilesForScan (
57
55
filesMetadata : IacFileMetadata [ ] ,
58
56
) : Promise < IacFileData [ ] > {
59
57
const parsedFileData : Array < IacFileData > = [ ] ;
@@ -62,25 +60,23 @@ async function parseFileContentsForPolicyEngine(
62
60
fileMetadata . filePath ,
63
61
'utf-8' ,
64
62
) ;
65
- const yamlDocuments = YAML . safeLoadAll ( fileContent ) ;
66
-
67
- yamlDocuments . forEach ( ( parsedYamlDocument , docId ) => {
68
- if (
69
- REQUIRED_K8S_FIELDS . every ( ( requiredField ) =>
70
- parsedYamlDocument . hasOwnProperty ( requiredField ) ,
71
- )
72
- ) {
73
- parsedFileData . push ( {
74
- ...fileMetadata ,
75
- fileContent : fileContent ,
76
- jsonContent : parsedYamlDocument ,
77
- docId,
78
- } ) ;
79
- } else {
80
- throw new Error ( 'Invalid K8s File!' ) ;
81
- }
82
- } ) ;
63
+ const parsedFiles = tryParseIacFile ( fileMetadata , fileContent ) ;
64
+ parsedFileData . push ( ...parsedFiles ) ;
83
65
}
84
66
85
67
return parsedFileData ;
86
68
}
69
+
70
+ async function scanFilesForIssues (
71
+ parsedFiles : Array < IacFileData > ,
72
+ ) : Promise < IacFileScanResult [ ] > {
73
+ // TODO: when adding dir support move implementation to queue.
74
+ // TODO: when adding dir support gracefully handle failed scans
75
+ return Promise . all (
76
+ parsedFiles . map ( async ( file ) => {
77
+ const policyEngine = await getPolicyEngine ( file . engineType ) ;
78
+ const scanResults = policyEngine . scanFile ( file ) ;
79
+ return scanResults ;
80
+ } ) ,
81
+ ) ;
82
+ }
0 commit comments