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

chore: Rewrite terraform_validate to common::per_dir_hook #404

Merged
merged 2 commits into from
Jul 4, 2022
Merged
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
128 changes: 55 additions & 73 deletions hooks/terraform_validate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,26 @@ function main {
common::initialize "$SCRIPT_DIR"
parse_cmdline_ "$@"
common::parse_and_export_env_vars
terraform_validate_

# Export provided env var K/V pairs to environment
local var var_name var_value
for var in "${ENVS[@]}"; do
var_name="${var%%=*}"
var_value="${var#*=}"
# shellcheck disable=SC2086
export $var_name="$var_value"
done
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved

# shellcheck disable=SC2153 # False positive
common::per_dir_hook "${ARGS[*]}" "$HOOK_ID" "${FILES[@]}"
}

#######################################################################
# Parse args and filenames passed to script and populate respective
# global variables with appropriate values
# Globals (init and populate):
# ARGS (array) arguments that configure wrapped tool behavior
# HOOK_CONFIG (array) arguments that configure hook behavior
# INIT_ARGS (array) arguments to `terraform init` command
# ENVS (array) environment variables that will be used with
# `terraform` commands
Expand All @@ -45,6 +57,11 @@ function parse_cmdline_ {
ARGS+=("$1")
shift
;;
-h | --hook-config)
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved
shift
HOOK_CONFIG+=("$1;")
shift
;;
-i | --init-args)
shift
INIT_ARGS+=("$1")
Expand All @@ -65,88 +82,53 @@ function parse_cmdline_ {
}

#######################################################################
# Wrapper around `terraform validate` tool that checks if code is valid
# 1. Export provided env var K/V pairs to environment
# 2. Because hook runs on whole dir, reduce file paths to uniq dir paths
# 3. In each dir that have *.tf files:
# 3.1. Check if `.terraform` dir exists and if not - run `terraform init`
# 3.2. Run `terraform validate`
# 3.3. If at least 1 check failed - change exit code to non-zero
# 4. Complete hook execution and return exit code
# Unique part of `common::per_dir_hook`. The function is executed in loop
# on each provided dir path. Run wrapped tool with specified arguments
# 1. Check if `.terraform` dir exists and if not - run `terraform init`
# 2. Run `terraform validate`
# 3. If at least 1 check failed - change the exit code to non-zero
# Arguments:
# args (string with array) arguments that configure wrapped tool behavior
# dir_path (string) PATH to dir relative to git repo root.
# Can be used in error logging
# Globals:
# ARGS (array) arguments that configure wrapped tool behavior
# INIT_ARGS (array) arguments for `terraform init` command`
# ENVS (array) environment variables that will be used with
# `terraform` commands
# FILES (array) filenames to check
# Outputs:
# If failed - print out hook checks status
#######################################################################
function terraform_validate_ {

# Setup environment variables
local var var_name var_value
for var in "${ENVS[@]}"; do
var_name="${var%%=*}"
var_value="${var#*=}"
# shellcheck disable=SC2086
export $var_name="$var_value"
done

declare -a paths
local index=0
local error=0

local file_with_path
for file_with_path in "${FILES[@]}"; do
file_with_path="${file_with_path// /__REPLACED__SPACE__}"

paths[index]=$(dirname "$file_with_path")
((index += 1))
done

local dir_path
for dir_path in $(echo "${paths[*]}" | tr ' ' '\n' | sort -u); do
dir_path="${dir_path//__REPLACED__SPACE__/ }"

if [[ -n "$(find "$dir_path" -maxdepth 1 -name '*.tf' -print -quit)" ]]; then

pushd "$(cd "$dir_path" > /dev/null && pwd -P)" > /dev/null

if [ ! -d .terraform ]; then
set +e
init_output=$(terraform init -backend=false "${INIT_ARGS[@]}" 2>&1)
init_code=$?
set -e

if [ $init_code -ne 0 ]; then
error=1
echo "Init before validation failed: $dir_path"
echo "$init_output"
popd > /dev/null
continue
fi
fi

set +e
validate_output=$(terraform validate "${ARGS[@]}" 2>&1)
validate_code=$?
set -e

if [ $validate_code -ne 0 ]; then
error=1
echo "Validation failed: $dir_path"
echo "$validate_output"
echo
fi

popd > /dev/null
function per_dir_hook_unique_part {
local -r args="$1"
local -r dir_path="$2"

local exit_code
local init_output
local validate_output

if [ ! -d .terraform ]; then
init_output=$(terraform init -backend=false "${INIT_ARGS[@]}" 2>&1)
exit_code=$?

if [ $exit_code -ne 0 ]; then
common::colorify "yellow" "'terraform init' failed, 'terraform validate' skipped: $dir_path"
echo "$init_output"
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved
return $exit_code
fi
done
fi
MaxymVlasov marked this conversation as resolved.
Show resolved Hide resolved

if [ $error -ne 0 ]; then
exit 1
# pass the arguments to hook
# shellcheck disable=SC2068 # hook fails when quoting is used ("$arg[@]")
validate_output=$(terraform validate ${args[@]} 2>&1)
exit_code=$?

if [ $exit_code -ne 0 ]; then
common::colorify "red" "Validation failed: $dir_path"
echo -e "$validate_output\n\n"
fi

# return exit code to common::per_dir_hook
return $exit_code
}

# global arrays
Expand Down