mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-07 05:04:28 +08:00
Add checkov linter for cloudformation
Co-Authored-By: jhandsel <64368631+jhandsel@users.noreply.github.com>
This commit is contained in:
41
ale_linters/cloudformation/checkov.vim
Normal file
41
ale_linters/cloudformation/checkov.vim
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
" Author: J. Handsel <jennpbc@posteo.net>, Thyme-87 <thyme-87@posteo.me>
|
||||||
|
" Description: use checkov for providing warnings for cloudformation via ale
|
||||||
|
|
||||||
|
call ale#Set('cloudformation_checkov_executable', 'checkov')
|
||||||
|
call ale#Set('cloudformation_checkov_options', '')
|
||||||
|
|
||||||
|
function! ale_linters#cloudformation#checkov#GetExecutable(buffer) abort
|
||||||
|
return ale#Var(a:buffer, 'cloudformation_checkov_executable')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#cloudformation#checkov#GetCommand(buffer) abort
|
||||||
|
return '%e ' . '-f %t -o json --quiet --framework cloudformation ' . ale#Var(a:buffer, 'cloudformation_checkov_options')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#cloudformation#checkov#Handle(buffer, lines) abort
|
||||||
|
let l:output = []
|
||||||
|
|
||||||
|
let l:results = get(get(ale#util#FuzzyJSONDecode(a:lines, {}), 'results', []), 'failed_checks', [])
|
||||||
|
|
||||||
|
for l:violation in l:results
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'filename': l:violation['file_path'],
|
||||||
|
\ 'lnum': l:violation['file_line_range'][0],
|
||||||
|
\ 'end_lnum': l:violation['file_line_range'][1],
|
||||||
|
\ 'text': l:violation['check_name'] . ' [' . l:violation['check_id'] . ']',
|
||||||
|
\ 'detail': l:violation['check_id'] . ': ' . l:violation['check_name'] . "\n" .
|
||||||
|
\ 'For more information, see: '. l:violation['guideline'],
|
||||||
|
\ 'type': 'W',
|
||||||
|
\ })
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('cloudformation', {
|
||||||
|
\ 'name': 'checkov',
|
||||||
|
\ 'output_stream': 'stdout',
|
||||||
|
\ 'executable': function('ale_linters#cloudformation#checkov#GetExecutable'),
|
||||||
|
\ 'command': function('ale_linters#cloudformation#checkov#GetCommand'),
|
||||||
|
\ 'callback': 'ale_linters#cloudformation#checkov#Handle',
|
||||||
|
\})
|
||||||
@@ -41,5 +41,51 @@ Just put the following in `ftdetect/cloudformation.vim`: >
|
|||||||
This will get both cloudformation and yaml linters to work on any file with
|
This will get both cloudformation and yaml linters to work on any file with
|
||||||
`.template.yaml` extension.
|
`.template.yaml` extension.
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
checkov *ale-cloudformation-checkov*
|
||||||
|
|
||||||
|
*ale-options.cloudformation_checkov_executable*
|
||||||
|
*g:ale_cloudformation_checkov_executable*
|
||||||
|
*b:ale_cloudformation_checkov_executable*
|
||||||
|
cloudformation_checkov_executable
|
||||||
|
g:ale_cloudformation_checkov_executable
|
||||||
|
Type: |String|
|
||||||
|
Default: `'checkov'`
|
||||||
|
|
||||||
|
This variable can be changed to use a different executable for checkov.
|
||||||
|
|
||||||
|
*ale-options.cloudformation_checkov_options*
|
||||||
|
*g:ale_cloudformation_checkov_options*
|
||||||
|
*b:ale_cloudformation_checkov_options*
|
||||||
|
cloudformation_checkov_options
|
||||||
|
g:ale_cloudformation_checkov_options
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
This variable can be changed to set additional options for checkov.
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Configuration
|
||||||
|
|
||||||
|
To get chekov to work with cloudformation files (rather than general yaml
|
||||||
|
files) we must set the buffer |filetype| to `yaml.cloudformation`. This
|
||||||
|
causes ALE to lint the file with linters configured for cloudformation and
|
||||||
|
YAML files.
|
||||||
|
|
||||||
|
One option is to put the following in `ftdetect/cloudformation.vim`: >
|
||||||
|
|
||||||
|
au BufRead,BufNewFile *.template.yaml set filetype=yaml.cloudformation
|
||||||
|
|
||||||
|
This will get both cloudformation and yaml linters to work on any file with
|
||||||
|
`.template.yaml` extension.
|
||||||
|
|
||||||
|
Another option is to check for the presence of 'AWSTemplateFormatVersion' in
|
||||||
|
the yaml file: >
|
||||||
|
|
||||||
|
au BufRead,BufNewFile *.yaml,*.yml if search('AWSTemplateFormatVersion', 'nw') | set filetype=yaml.cloudformation | endif
|
||||||
|
<
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ Notes:
|
|||||||
* `joker`
|
* `joker`
|
||||||
* CloudFormation
|
* CloudFormation
|
||||||
* `cfn-python-lint`
|
* `cfn-python-lint`
|
||||||
|
* `checkov`
|
||||||
* CMake
|
* CMake
|
||||||
* `cmake-format`
|
* `cmake-format`
|
||||||
* `cmake-lint`
|
* `cmake-lint`
|
||||||
|
|||||||
@@ -3419,6 +3419,7 @@ documented in additional help files.
|
|||||||
joker.................................|ale-clojure-joker|
|
joker.................................|ale-clojure-joker|
|
||||||
cloudformation..........................|ale-cloudformation-options|
|
cloudformation..........................|ale-cloudformation-options|
|
||||||
cfn-python-lint.......................|ale-cloudformation-cfn-python-lint|
|
cfn-python-lint.......................|ale-cloudformation-cfn-python-lint|
|
||||||
|
checkov...............................|ale-cloudformation-checkov|
|
||||||
cmake...................................|ale-cmake-options|
|
cmake...................................|ale-cmake-options|
|
||||||
cmakelint.............................|ale-cmake-cmakelint|
|
cmakelint.............................|ale-cmake-cmakelint|
|
||||||
cmake-lint............................|ale-cmake-cmake-lint|
|
cmake-lint............................|ale-cmake-cmake-lint|
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ formatting.
|
|||||||
* [joker](https://github.com/candid82/joker)
|
* [joker](https://github.com/candid82/joker)
|
||||||
* CloudFormation
|
* CloudFormation
|
||||||
* [cfn-python-lint](https://github.com/awslabs/cfn-python-lint)
|
* [cfn-python-lint](https://github.com/awslabs/cfn-python-lint)
|
||||||
|
* [checkov](https://github.com/bridgecrewio/checkov)
|
||||||
* CMake
|
* CMake
|
||||||
* [cmake-format](https://github.com/cheshirekow/cmake_format)
|
* [cmake-format](https://github.com/cheshirekow/cmake_format)
|
||||||
* [cmake-lint](https://github.com/cheshirekow/cmake_format)
|
* [cmake-lint](https://github.com/cheshirekow/cmake_format)
|
||||||
|
|||||||
86
test/handler/test_cloudformation_checkov_handler.vader
Normal file
86
test/handler/test_cloudformation_checkov_handler.vader
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
Before:
|
||||||
|
runtime ale_linters/cloudformation/checkov.vim
|
||||||
|
call ale#test#SetFilename('sample.template.yaml')
|
||||||
|
|
||||||
|
After:
|
||||||
|
call ale#linter#Reset()
|
||||||
|
|
||||||
|
Execute(Handle output for no findings correctly):
|
||||||
|
AssertEqual
|
||||||
|
\ [],
|
||||||
|
\ ale_linters#cloudformation#checkov#Handle(bufnr(''), [
|
||||||
|
\'{',
|
||||||
|
\' "passed": 0,',
|
||||||
|
\' "failed": 0,',
|
||||||
|
\' "skipped": 0,',
|
||||||
|
\' "parsing_errors": 0,',
|
||||||
|
\' "resource_count": 0,',
|
||||||
|
\' "checkov_version": "3.2.415"',
|
||||||
|
\'}'
|
||||||
|
\])
|
||||||
|
|
||||||
|
Execute(Handle output for all tests passed):
|
||||||
|
AssertEqual
|
||||||
|
\ [],
|
||||||
|
\ ale_linters#cloudformation#checkov#Handle(bufnr(''), [
|
||||||
|
\'{',
|
||||||
|
\' "check_type": "cloudformation",',
|
||||||
|
\' "results": {',
|
||||||
|
\' "failed_checks": []',
|
||||||
|
\' },',
|
||||||
|
\' "summary": {',
|
||||||
|
\' "passed": 18,',
|
||||||
|
\' "failed": 0,',
|
||||||
|
\' "skipped": 0,',
|
||||||
|
\' "parsing_errors": 0,',
|
||||||
|
\' "resource_count": 3,',
|
||||||
|
\' "checkov_version": "3.2.415"',
|
||||||
|
\' }',
|
||||||
|
\'}'
|
||||||
|
\])
|
||||||
|
|
||||||
|
Execute(The JSON output of checkov should be handled correctly):
|
||||||
|
AssertEqual
|
||||||
|
\ [
|
||||||
|
\ {
|
||||||
|
\ 'filename': '/sample.template.yaml',
|
||||||
|
\ 'lnum': 57,
|
||||||
|
\ 'end_lnum': 79,
|
||||||
|
\ 'text': 'Ensure that AWS Lambda function is configured for a Dead Letter Queue(DLQ) [CKV_AWS_116]',
|
||||||
|
\ 'detail': "CKV_AWS_116: Ensure that AWS Lambda function is configured for a Dead Letter Queue(DLQ)\n" .
|
||||||
|
\ 'For more information, see: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-general-policies/ensure-that-aws-lambda-function-is-configured-for-a-dead-letter-queue-dlq',
|
||||||
|
\ 'type': 'W',
|
||||||
|
\ }
|
||||||
|
\ ],
|
||||||
|
\ ale_linters#cloudformation#checkov#Handle(bufnr(''), [
|
||||||
|
\'{',
|
||||||
|
\' "check_type": "cloudformation",',
|
||||||
|
\' "results": {',
|
||||||
|
\' "failed_checks": [',
|
||||||
|
\' {',
|
||||||
|
\' "check_id": "CKV_AWS_116",',
|
||||||
|
\' "bc_check_id": "BC_AWS_GENERAL_64",',
|
||||||
|
\' "check_name": "Ensure that AWS Lambda function is configured for a Dead Letter Queue(DLQ)",',
|
||||||
|
\' "check_result": {',
|
||||||
|
\' "result": "FAILED",',
|
||||||
|
\' "evaluated_keys": [',
|
||||||
|
\' "Properties/DeadLetterQueue/TargetArn"',
|
||||||
|
\' ]',
|
||||||
|
\' },',
|
||||||
|
\' "file_path": "/sample.template.yaml",',
|
||||||
|
\' "repo_file_path": "/sample.template.yaml",',
|
||||||
|
\' "file_line_range": [',
|
||||||
|
\' 57,',
|
||||||
|
\' 79',
|
||||||
|
\' ],',
|
||||||
|
\' "resource": "AWS::Serverless::Function.FunctionName",',
|
||||||
|
\' "evaluations": {},',
|
||||||
|
\' "check_class": "checkov.cloudformation.checks.resource.aws.LambdaDLQConfigured",',
|
||||||
|
\' "entity_tags": null,',
|
||||||
|
\' "resource_address": null,',
|
||||||
|
\' "guideline": "https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-general-policies/ensure-that-aws-lambda-function-is-configured-for-a-dead-letter-queue-dlq"',
|
||||||
|
\' }',
|
||||||
|
\' ]',
|
||||||
|
\' }',
|
||||||
|
\'}'
|
||||||
|
\ ])
|
||||||
15
test/linter/test_cloudformation_checkov.vader
Normal file
15
test/linter/test_cloudformation_checkov.vader
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Before:
|
||||||
|
call ale#assert#SetUpLinterTest('cloudformation', 'checkov')
|
||||||
|
|
||||||
|
After:
|
||||||
|
call ale#assert#TearDownLinterTest()
|
||||||
|
|
||||||
|
Execute(The default command should be direct):
|
||||||
|
AssertLinter 'checkov',
|
||||||
|
\ ale#Escape('checkov') . ' -f %t -o json --quiet --framework cloudformation '
|
||||||
|
|
||||||
|
Execute(It should be possible to override the default command):
|
||||||
|
let b:ale_cloudformation_checkov_executable = '/bin/other/checkov'
|
||||||
|
AssertLinter '/bin/other/checkov',
|
||||||
|
\ ale#Escape('/bin/other/checkov') . ' -f %t -o json --quiet --framework cloudformation '
|
||||||
|
|
||||||
Reference in New Issue
Block a user