Skip to content

Commit

Permalink
fix: adding support for dynamic mounting dir (#292)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChiefHolland authored Sep 19, 2023
1 parent 2af6c3e commit e7ad404
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 3 deletions.
20 changes: 17 additions & 3 deletions build/functions.j2
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ function process_command_exit_status() {
{%- set monitor = packages[package]["monitor"] -%}

function {{ "scan_" ~ function if scan else function }}() {
_feedback DEBUGGING "Entering the ${FUNCNAME[0]} function..."
arguments=("${@}")
easy_infra_{{ function | replace("-", "_") }}_security_tools=({% for security_tool in security_tools %}{{ security_tool | replace("-", "_") }}{% if not loop.last %} {% endif %}{% endfor %})

Expand Down Expand Up @@ -117,25 +118,32 @@ function {{ "scan_" ~ function if scan else function }}() {
for file in /opt/hooks/bin/*.sh; do
command=$(awk -F\: '/register_hook/ { gsub(/ /,""); print $2 }' "${file}")
if [[ "${command}" == "{{ 'scan_' ~ function if scan else function }}" ]]; then
_feedback DEBUGGING "Registering ${file} to the ${FUNCNAME[0]} hooks"
easy_infra_{{ function | replace("-", "_") }}_hooks+=("${file}")
fi
done
fi

# This attempts to detect a .git directory in the work dir and adds it as a safe directory to prevent errors when generating git context for logs.
# Adds the detected git toplevel as a safe directory to prevent errors when generating git context for logs.
current_dir=$(pwd -P)
export GIT_CONFIG_COUNT=1
_feedback DEBUGGING "Set GIT_CONFIG_COUNT to ${GIT_CONFIG_COUNT}"
export GIT_CONFIG_KEY_0="safe.directory"
GIT_CONFIG_VALUE_0="$(git rev-parse --show-toplevel 2>/dev/null || echo /iac)"
_feedback DEBUGGING "Set GIT_CONFIG_KEY_0 to ${GIT_CONFIG_KEY_0}"
GIT_CONFIG_VALUE_0="$(git rev-parse --show-toplevel 2>/dev/null || echo ${current_dir})"
export GIT_CONFIG_VALUE_0
_feedback DEBUGGING "Set GIT_CONFIG_VALUE_0 to ${GIT_CONFIG_VALUE_0}"

# Methods to skip **all** security tools for {{ function }}{% for filter in allow_filter if allow_filter is defined %} {{ filter['match'] }}{% endfor %}
DISABLE_SECURITY="${DISABLE_SECURITY:-false}"
dirs=()
_feedback DEBUGGING "AUTODETECT is ${AUTODETECT:-not set}"
if [[ "${AUTODETECT:-false}" == "true" ]]; then
{%- if file_extensions is defined %}
{%- for file_extension in file_extensions %}
files=$(find . -iname "*.{{ file_extension }}" -type f)
if [[ "${files}" ]]; then
_feedback DEBUGGING "Adding to the dirs loop due to detecting files with the {{ file_extension }} extension: ${files}"
dirs+=($(for file in ${files}; do dirname ${file}; done | sort -u | xargs readlink --canonicalize))
fi
{%- endfor %}
Expand All @@ -151,12 +159,18 @@ function {{ "scan_" ~ function if scan else function }}() {

declare -A dir_exit_codes

if [ "{{ '${' }}#dirs[@]}" -eq 0 ]; then
_feedback WARNING "The function ${FUNCNAME[0]} has no directories to iterate through; did you run ${FUNCNAME[0]} with AUTODETECT=true but with no matching files in any subdirectories?"
else
_feedback DEBUGGING "The final dirs array is ${dirs[*]:-empty}"
fi

for dir in "${dirs[@]}"; do
_feedback INFO "Changing into the ${dir} directory..."
pushd "${dir}" > /dev/null

# Keep the git config value aligned with the current directory
GIT_CONFIG_VALUE_0="$(git rev-parse --show-toplevel 2>/dev/null || echo /iac)"
GIT_CONFIG_VALUE_0="$(git rev-parse --show-toplevel 2>/dev/null || echo ${current_dir})"

# Export variables to be used in the hooks
export dir
Expand Down
63 changes: 63 additions & 0 deletions tests/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,9 @@ def run_cloudformation(*, image: str, user: str) -> None:
secure_volumes: dict[Path, dict[str, str]] = {
secure_test_dir: {"bind": working_dir, "mode": "rw"}
}
alt_working_dir: str = "/alt_working_dir/"
alt_bind_secure_volumes = copy.deepcopy(secure_volumes)
alt_bind_secure_volumes[secure_test_dir]["bind"] = alt_working_dir
checkov_test_dir: Path = cloudformation_test_dir.joinpath("tool/checkov")
checkov_volumes: dict[Path, dict[str, str]] = {
checkov_test_dir: {"bind": working_dir, "mode": "rw"}
Expand All @@ -479,6 +482,22 @@ def run_cloudformation(*, image: str, user: str) -> None:
"checkov.json"
)

# Test alternative working directories/binds
# Tests is a list of tuples containing the test environment, command, and expected exit code
tests: list[tuple[dict, str, int]] = [ # type: ignore
(
{"AWS_DEFAULT_REGION": "ap-northeast-1"},
"aws cloudformation validate-template --template-body file://./secure.yml",
253,
),
({}, "scan_cloudformation", 0),
]

LOG.debug("Testing alternative working dirs/binds with the cloudformation image")
num_tests_ran += exec_tests(
tests=tests, volumes=alt_bind_secure_volumes, image=image, user=user
)

# Ensure secure configurations pass
# Tests is a list of tuples containing the test environment, command, and expected exit code
tests: list[tuple[dict, str, int]] = [ # type: ignore
Expand Down Expand Up @@ -743,6 +762,9 @@ def run_terraform(*, image: str, user: str) -> None:
secure_volumes: dict[Path, dict[str, str]] = {
secure_config_dir: {"bind": working_dir, "mode": "rw"}
}
alt_working_dir: str = "/alt_working_dir/"
alt_bind_secure_volumes = copy.deepcopy(secure_volumes)
alt_bind_secure_volumes[secure_config_dir]["bind"] = alt_working_dir
general_test_dir: Path = terraform_test_dir.joinpath("general")
general_test_volumes: dict[Path, dict[str, str]] = {
general_test_dir: {"bind": working_dir, "mode": "rw"}
Expand Down Expand Up @@ -1009,6 +1031,28 @@ def run_terraform(*, image: str, user: str) -> None:

num_tests_ran += num_successful_tests

# Test alternative working directories/binds
# Tests is a list of tuples containing the test environment, command, and expected exit code
tests: list[tuple[dict, str, int]] = [ # type: ignore
({}, "terraform init", 0),
({}, "tfenv exec init", 0),
(
{},
'/usr/bin/env bash -c "terraform init && false"',
1,
),
(
{},
'/usr/bin/env bash -c "tfenv exec init && false"',
1,
),
]

LOG.debug("Testing alternative working dirs/binds with the terraform image")
num_tests_ran += exec_tests(
tests=tests, volumes=alt_bind_secure_volumes, image=image, user=user
)

# Ensure secure configurations pass
# Tests is a list of tuples containing the test environment, command, and expected exit code
tests: list[tuple[dict, str, int]] = [ # type: ignore
Expand Down Expand Up @@ -1424,13 +1468,32 @@ def run_ansible(*, image: str, user: str) -> None:
secure_config_dir = TESTS_PATH.joinpath("ansible/general/secure")
secure_volumes = {secure_config_dir: {"bind": working_dir, "mode": "rw"}}
secure_volumes_with_log_config = copy.deepcopy(secure_volumes)
alt_working_dir: str = "/alt_working_dir/"
alt_bind_secure_volumes = copy.deepcopy(secure_volumes)
alt_bind_secure_volumes[secure_config_dir]["bind"] = alt_working_dir
fluent_bit_config_host = TESTS_PATH.joinpath("fluent-bit.outputs.conf")
fluent_bit_config_container = "/usr/local/etc/fluent-bit/fluent-bit.outputs.conf"
secure_volumes_with_log_config[fluent_bit_config_host] = {
"bind": fluent_bit_config_container,
"mode": "ro",
}

# Test alternative working directories/binds
# Tests is a list of tuples containing the test environment, command, and expected exit code
tests: list[tuple[dict, str, int]] = [ # type: ignore
(
{},
"ansible-playbook secure.yml --syntax-check",
4,
), # Exits 4 because secure.yml is not a valid Play
({}, '/bin/bash -c "ansible-playbook secure.yml --syntax-check || false"', 1),
]

LOG.debug("Testing alternative working dirs/binds with the ansible image")
num_tests_ran += exec_tests(
tests=tests, volumes=alt_bind_secure_volumes, image=image, user=user
)

# Ensure insecure configurations fail due to kics
# Tests is a list of tuples containing the test environment, command, and
# expected exit code
Expand Down

0 comments on commit e7ad404

Please sign in to comment.