From ffda33bae90a2e6a4a83f8d73d0f5adfd3e771d8 Mon Sep 17 00:00:00 2001 From: Erik Osterman Date: Tue, 4 Jun 2019 19:50:57 -0700 Subject: [PATCH] [terraform] 0.12 support (#7) * Terraform 0.12 support * Terraform 0.12 support * drop empty scrit * Update module pinning test * fix tests * fix tests * reduce noise * support no modules at all * Update test/terraform/validate.bats --- test/terraform/input-descriptions.bats | 11 +++++- test/terraform/lib.bash | 16 +++++++++ test/terraform/module-pinning.bats | 14 +++++--- test/terraform/output-descriptions.bats | 11 +++++- test/terraform/terraform-docs.awk | 46 +++++++++++++++++++++++++ test/terraform/validate.bats | 24 ++++++++++--- 6 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 test/terraform/terraform-docs.awk diff --git a/test/terraform/input-descriptions.bats b/test/terraform/input-descriptions.bats index 54cd9b3..2ceeece 100644 --- a/test/terraform/input-descriptions.bats +++ b/test/terraform/input-descriptions.bats @@ -1,8 +1,17 @@ load 'lib' +function setup() { + TMPFILE="$(mktemp /tmp/terraform-docs-XXXXXXXXXXX.json)" +} + +function teardown() { + rm -f $TMPFILE +} + @test "check if terraform inputs have descriptions" { skip_unless_terraform - run bash -c "terraform-docs json . | jq -rS '.Inputs[] | select (.Description == \"\") | .Name'" + terraform_docs json . > $TMPFILE + run bash -c "jq -rS '.Inputs[] | select (.Description == \"\") | .Name + \" is missing a description\"' < $TMPFILE" log "$output" [ -z "$output" ] } diff --git a/test/terraform/lib.bash b/test/terraform/lib.bash index 9bd3fe7..06d5546 100644 --- a/test/terraform/lib.bash +++ b/test/terraform/lib.bash @@ -40,3 +40,19 @@ function clean() { function skip_unless_terraform() { [[ -n $(echo *.tf) ]] || skip "no *.tf files" } + +function terraform_docs() { + local TMP_FILE + which awk 2>&1 >/dev/null || ( echo "awk not available"; exit 1) + which terraform 2>&1 >/dev/null || ( echo "terraform not available"; exit 1) + which terraform-docs 2>&1 >/dev/null || ( echo "terraform-docs not available"; exit 1) + + if [[ "`terraform version | head -1`" =~ 0\.12 ]]; then + TMP_FILE="$(mktemp /tmp/terraform-docs-XXXXXXXXXX.tf)" + awk -f ${BATS_TEST_DIRNAME}/terraform-docs.awk $2/*.tf > ${TMP_FILE} + terraform-docs $1 ${TMP_FILE} + rm -f ${TMP_FILE} + else + terraform-docs $1 $2 + fi +} diff --git a/test/terraform/module-pinning.bats b/test/terraform/module-pinning.bats index a8c3c94..bc90118 100644 --- a/test/terraform/module-pinning.bats +++ b/test/terraform/module-pinning.bats @@ -1,16 +1,22 @@ load 'lib' function setup() { -: + TMPFILE="$(mktemp /tmp/terraform-modules-XXXXXXXXXXX.txt)" } function teardown() { + #rm -f $TMPFILE : } @test "check if terraform modules are properly pinned" { skip_unless_terraform - run bash -c "cat *.tf | json2hcl -reverse | jq -r '..|select(.source?)|.source' | sort -u | sed 's/^.*?ref=//' | grep -Ev '^(tags/[0-9]+\\.[0-9]+.*|)$$'" - log "$output" - [ $status -ne 0 ] + grep -Eo '^\s*source\s*=\s*"(.*?)"' *.tf | cut -d'"' -f2 | sort -u > $TMPFILE + if [ -s $TMPFILE ]; then + # Verify the modules are pinned to `tags/x.y` or nothing at all (maybe using `version` parameter instead) + sed 's/^.*?ref=//' < $TMPFILE | grep -E '^(tags/[0-9]+\.[0-9]+.*|)$' + else + # If the file is empty, then no modules are being used + true + fi } diff --git a/test/terraform/output-descriptions.bats b/test/terraform/output-descriptions.bats index fa67108..62eea59 100644 --- a/test/terraform/output-descriptions.bats +++ b/test/terraform/output-descriptions.bats @@ -1,8 +1,17 @@ load 'lib' +function setup() { + TMPFILE="$(mktemp /tmp/terraform-docs-XXXXXXXXXXX.json)" +} + +function teardown() { + rm -f $TMPFILE +} + @test "check if terraform outputs have descriptions" { skip_unless_terraform - run bash -c "terraform-docs json . | jq -rS '.Outputs[] | select (.Description == \"\") | .Name'" + terraform_docs json . > $TMPFILE + run bash -c "jq -rS '.Outputs[] | select (.Description == \"\") | .Name + \" is missing a description\"' < $TMPFILE" log "$output" [ -z "$output" ] } diff --git a/test/terraform/terraform-docs.awk b/test/terraform/terraform-docs.awk new file mode 100644 index 0000000..a627c09 --- /dev/null +++ b/test/terraform/terraform-docs.awk @@ -0,0 +1,46 @@ +# This script converts Terraform 0.12 variables/outputs to something suitable for `terraform-docs` +# As of terraform-docs v0.6.0, HCL2 is not supported. This script is a *dirty hack* to get around it. +# https://github.com/segmentio/terraform-docs/ +# https://github.com/segmentio/terraform-docs/issues/62 + +{ + if ( /\{/ ) { + braceCnt++ + } + + if ( /\}/ ) { + braceCnt-- + } + + if ($0 ~ /(variable|output) "(.*?)"/) { + blockCnt++ + print $0 + } + + if ($1 == "description") { + print $0 + } + + if ($1 == "default") { + if (braceCnt > 1) { + print " default = {}" + } else { + print $0 + } + } + + if ($1 == "type" ) { + type=$3 + if (type ~ "object") { + print " type = \"object\"" + } else { + gsub(/"/, "", $3) + print " type = \"" $3 "\"" + } + } + + if (braceCnt == 0 && blockCnt > 0) { + blockCnt-- + print $0 + } +} diff --git a/test/terraform/validate.bats b/test/terraform/validate.bats index d9a6eb5..52e3a18 100644 --- a/test/terraform/validate.bats +++ b/test/terraform/validate.bats @@ -1,9 +1,25 @@ load 'lib' +function setup() { + skip_unless_terraform + clean + export TF_CLI_ARGS_init="-input=false -backend=false" + terraform init +} + +function teardown() { + clean + unset TF_CLI_ARGS_plan +} + @test "check if terraform code is valid" { skip_unless_terraform - run terraform validate -check-variables=false - log "$output" - [ $status -eq 0 ] - [ -z "$output" ] + if [[ "`terraform version | head -1`" =~ 0\.12 ]]; then + run terraform validate . + [ $status -eq 0 ] + else + run terraform validate -check-variables=false + [ $status -eq 0 ] + [ -z "$output" ] + fi }