Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: adding support for dynamic mounting dir #292

Merged
merged 8 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
JonZeolla marked this conversation as resolved.
Show resolved Hide resolved
_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/"
JonZeolla marked this conversation as resolved.
Show resolved Hide resolved
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