Skip to content

Commit d28f6b5

Browse files
authored
feat(general): Change behavior where if a config file is missing, run the scan as if there was no config file (bridgecrewio#6926)
* Initial commit * fix mock issue * fix for windows * Moving to env var * fix flake8 * Update CLI Command Reference.md * Add other variables
1 parent cb2283f commit d28f6b5

File tree

4 files changed

+57
-1
lines changed

4 files changed

+57
-1
lines changed

checkov/common/util/env_vars_config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def __init__(self) -> None:
8383
self.PROXY_URL = os.getenv('PROXY_URL', None)
8484
self.PROXY_HEADER_VALUE = os.getenv('PROXY_HEADER_VALUE', None)
8585
self.PROXY_HEADER_KEY = os.getenv('PROXY_HEADER_VALUE', None)
86+
self.ENABLE_CONFIG_FILE_VALIDATION = convert_str_to_bool(os.getenv("ENABLE_CONFIG_FILE_VALIDATION", False))
8687

8788

8889
env_vars_config = EnvVarsConfig()

checkov/main.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
from checkov.common.util.ext_argument_parser import ExtArgumentParser, flatten_csv
5959
from checkov.common.util.runner_dependency_handler import RunnerDependencyHandler
6060
from checkov.common.util.type_forcers import convert_str_to_bool
61+
from checkov.common.util.env_vars_config import env_vars_config
6162
from checkov.contributor_metrics import report_contributor_metrics
6263
from checkov.dockerfile.runner import Runner as dockerfile_runner
6364
from checkov.docs_generator import print_checks
@@ -163,7 +164,7 @@ def _parse_mask_to_resource_attributes_to_omit(self) -> None:
163164
self.config.mask = resource_attributes_to_omit
164165

165166
def parse_config(self, argv: list[str] = sys.argv[1:]) -> None:
166-
"""Parses the user defined config via CLI flags"""
167+
"""Parses the user-defined config via CLI flags and handles missing config-file"""
167168

168169
default_config_paths = get_default_config_paths(sys.argv[1:])
169170
self.parser = ExtArgumentParser(
@@ -175,6 +176,15 @@ def parse_config(self, argv: list[str] = sys.argv[1:]) -> None:
175176
self.parser.add_parser_args()
176177
argcomplete.autocomplete(self.parser)
177178

179+
# Pre-validate the config-file argument
180+
if env_vars_config.ENABLE_CONFIG_FILE_VALIDATION:
181+
for i, arg in enumerate(argv):
182+
if arg == "--config-file" and i + 1 < len(argv):
183+
config_path = Path(argv[i + 1])
184+
if not config_path.is_file():
185+
logger.debug(f"The config file at '{config_path}' does not exist. Running without a config file.")
186+
argv[i + 1] = "" # Clear the non-existent file from arguments
187+
178188
self.config = self.parser.parse_args(argv)
179189
self.normalize_config()
180190

docs/2.Basics/CLI Command Reference.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,6 @@ nav_order: 2
7878
| `EVAL_TF_PLAN_AFTER_UNKNOWN` | Experimental feature to leverage the after_unknown section of plan files to determine if the check should pass or fail. | `False` |
7979
| `CHECKOV_EXPERIMENTAL_TERRAFORM_MANAGED_MODULES` | Experimental feature to leverage the local cache of modules rather than downloading them. Requires terraform init before using. | `False` |
8080
| `GITHUB_PAT`, `BITBUCKET_TOKEN`, `TF_REGISTRY_TOKEN`, `TF_HOST_NAME`, `VCS_BASE_URL`, `VCS_USERNAME`, `VCS_TOKEN` | See [Scanning Private Terraform Modules](https://www.checkov.io/7.Scan%20Examples/Terraform.html) for more details. |
81+
| `ENABLE_CONFIG_FILE_VALIDATION` | If the conf-file explicitly set using the `--config-file` command does not exist, skip rather than throw an error (default) | `False` |
82+
| `CHECKOV_MAX_IAC_FILE_SIZE` | Set the max size for CloudFormation file scans. | `50_000_000` or 50MB |
83+
| `CHECKOV_MAX_FILE_SIZE` | Set the max file size for Secrets scans. | `5000000` or 5MB |

integration_tests/test_checkov_config.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import json
22
import os
33
import unittest
4+
from unittest import mock
5+
from checkov.common.logger_streams import LoggerStreams
6+
from checkov.logging_init import log_stream, erase_log_stream
7+
from checkov.main import Checkov
8+
from checkov.common.util.env_vars_config import env_vars_config
49

510
current_dir = os.path.dirname(os.path.realpath(__file__))
611

@@ -29,6 +34,43 @@ def test_terragoat_report(self):
2934
data["results"]["failed_checks"][0]["guideline"], "expecting a guideline for checks."
3035
)
3136

37+
def setUp(self):
38+
erase_log_stream() # Clear any existing logs before each test
39+
self.logger_streams = LoggerStreams()
40+
self.stream_name = "test_stream"
41+
self.logger_streams.add_stream(self.stream_name, log_stream)
42+
43+
def tearDown(self):
44+
erase_log_stream() # Ensure logs are cleared after each test
45+
46+
def get_logged_messages(self):
47+
return self.logger_streams.get_streams().get(self.stream_name).getvalue()
48+
49+
def test_missing_config_file(self):
50+
"""Test when the provided config-file does not exist."""
51+
env_vars_config.ENABLE_CONFIG_FILE_VALIDATION = True
52+
config_path = os.path.join('path', 'to', 'missing', 'config.yaml')
53+
argv = ["--config-file", config_path]
54+
55+
with mock.patch("pathlib.Path.is_file", return_value=False):
56+
checkov_instance = Checkov(argv=argv)
57+
checkov_instance.parse_config()
58+
59+
logged_messages = self.get_logged_messages()
60+
expected_message = f"The config file at '{config_path}' does not exist. Running without a config file."
61+
self.assertIn(expected_message, logged_messages)
62+
63+
def test_no_config_file_argument(self):
64+
"""Test when no --config-file argument is provided."""
65+
env_vars_config.ENABLE_CONFIG_FILE_VALIDATION = True
66+
argv = []
67+
68+
checkov_instance = Checkov(argv=argv)
69+
checkov_instance.parse_config()
70+
71+
logged_messages = self.get_logged_messages()
72+
self.assertNotIn("does not exist", logged_messages)
73+
3274

3375
if __name__ == "__main__":
3476
unittest.main()

0 commit comments

Comments
 (0)