diff --git a/Gemfile b/Gemfile deleted file mode 100644 index cf3f389..0000000 --- a/Gemfile +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2019 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -ruby '2.5.3' - -source 'https://rubygems.org/' do - gem 'kitchen-terraform', '~> 4.2' -end diff --git a/Makefile b/Makefile index 6a10795..fc07305 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ # Make will use bash instead of sh SHELL := /usr/bin/env bash -DOCKER_TAG_VERSION_DEVELOPER_TOOLS := 0.1.0 +DOCKER_TAG_VERSION_DEVELOPER_TOOLS := 0.4.3 DOCKER_IMAGE_DEVELOPER_TOOLS := cft/developer-tools REGISTRY_URL := gcr.io/cloud-foundation-cicd diff --git a/README.md b/README.md index e447bd2..f5c71d4 100644 --- a/README.md +++ b/README.md @@ -26,24 +26,28 @@ The is a tested reference of how to use the root module with the [event-project-log-entry submodule][event-project-log-entry-submodule]. -[^]: (autogen_docs_start) - + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| available\_memory\_mb | The amount of memory in megabytes allotted for the function to use. | string | `"256"` | no | +| available\_memory\_mb | The amount of memory in megabytes allotted for the function to use. | number | `"256"` | no | +| bucket\_force\_destroy | When deleting the GCS bucket containing the cloud function, delete all objects in the bucket first. | bool | `"false"` | no | +| bucket\_labels | A set of key/value label pairs to assign to the function source archive bucket. | map(string) | `` | no | +| bucket\_name | The name to apply to the bucket. Will default to a string of the function name. | string | `""` | no | | description | The description of the function. | string | `"Processes events."` | no | | entry\_point | The name of a method in the function source which will be invoked when the function is executed. | string | n/a | yes | -| environment\_variables | A set of key/value environment variable pairs to assign to the function. | map | `` | no | -| event\_trigger | A source that fires events in response to a condition in another service. | map | n/a | yes | -| labels | A set of key/value label pairs to assign to any lableable resources. | map | `` | no | +| environment\_variables | A set of key/value environment variable pairs to assign to the function. | map(string) | `` | no | +| event\_trigger | A source that fires events in response to a condition in another service. | map(string) | n/a | yes | +| event\_trigger\_failure\_policy\_retry | A toggle to determine if the function should be retried on failure. | bool | `"false"` | no | +| labels | A set of key/value label pairs to assign to the Cloud Function. | map(string) | `` | no | | name | The name to apply to any nameable resources. | string | n/a | yes | | project\_id | The ID of the project to which resources will be applied. | string | n/a | yes | | region | The region in which resources will be applied. | string | n/a | yes | -| runtime | The runtime in which the function will be executed. | string | `"nodejs6"` | no | +| runtime | The runtime in which the function will be executed. | string | n/a | yes | +| service\_account\_email | The service account to run the function as. | string | `""` | no | | source\_directory | The pathname of the directory which contains the function source code. | string | n/a | yes | -| timeout\_s | The amount of time in seconds allotted for the execution of the function. | string | `"60"` | no | +| timeout\_s | The amount of time in seconds allotted for the execution of the function. | number | `"60"` | no | ## Outputs @@ -51,7 +55,7 @@ is a tested reference of how to use the root module with the |------|-------------| | name | The name of the function. | -[^]: (autogen_docs_end) + ## Requirements @@ -63,11 +67,10 @@ order to invoke this module. The following software dependencies must be installed on the system from which this module will be invoked: -- [Terraform][terraform-site] v0.12.Z +- [Terraform][terraform-site] v0.12 - [Terraform Provider for Archive][terraform-provider-archive-site] - v1.2.Z -- [Terraform Provider for Google Cloud Platform][terraform-provider-gcp-site] - v2.5.Z + v1.2 +- [Terraform Provider for Google Cloud Platform][terraform-provider-gcp-site] v2.5 ### IAM Roles @@ -87,3 +90,15 @@ following APIs enabled: The [Project Factory module][project-factory-module-site] can be used to provision projects with specific APIs activated. + +## Contributing + +Refer to the [contribution guidelines](./CONTRIBUTING.md) for +information on contributing to this module. + +[automatic-labelling-from-localhost-example]: examples/automatic-labelling-from-localhost +[event-project-log-entry-submodule]: modules/event-project-log-entry +[repository-function-submodule]: modules/repository-function +[project-factory-module-site]: https://github.com/terraform-google-modules/terraform-google-project-factory/ +[terraform-provider-gcp-site]: https://github.com/terraform-providers/terraform-provider-google/ +[terraform-site]: https://www.terraform.io/ diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index acdecf8..3a31d22 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -38,4 +38,4 @@ tags: - 'integration' substitutions: _DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools' - _DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.1.0' + _DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.4.3' diff --git a/build/lint.cloudbuild.yaml b/build/lint.cloudbuild.yaml index 779febf..afa64b4 100644 --- a/build/lint.cloudbuild.yaml +++ b/build/lint.cloudbuild.yaml @@ -21,4 +21,4 @@ tags: - 'lint' substitutions: _DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools' - _DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.1.0' + _DOCKER_TAG_VERSION_DEVELOPER_TOOLS: '0.4.3' diff --git a/examples/automatic-labelling-folder/README.md b/examples/automatic-labelling-folder/README.md index a5aa92a..62db919 100644 --- a/examples/automatic-labelling-folder/README.md +++ b/examples/automatic-labelling-folder/README.md @@ -25,6 +25,14 @@ this directory: | project\_id | The ID of the project to which resources will be applied. | string | n/a | yes | | region | The region in which resources will be applied. | string | n/a | yes | +## Outputs + +| Name | Description | +|------|-------------| +| project\_id | The ID of the project to which resources are applied. | +| region | The region in which resources are applied. | +| test\_project\_id | The ID of the project to test. | + ## Requirements @@ -40,7 +48,7 @@ must also be met. The following software dependencies must be installed on the system from which this module will be invoked: -- [Terraform][terraform-site] v0.12.Z +- [Terraform][terraform-site] v0.12 ### IAM Roles diff --git a/examples/automatic-labelling-folder/main.tf b/examples/automatic-labelling-folder/main.tf index 4ea2532..cc3e583 100644 --- a/examples/automatic-labelling-folder/main.tf +++ b/examples/automatic-labelling-folder/main.tf @@ -104,4 +104,4 @@ resource "google_project_iam_member" "test_project_iam" { project = google_project.test.project_id role = "roles/owner" member = "serviceAccount:${var.project_id}@appspot.gserviceaccount.com" -} \ No newline at end of file +} diff --git a/examples/automatic-labelling-from-localhost/README.md b/examples/automatic-labelling-from-localhost/README.md index bde0baf..03d440d 100644 --- a/examples/automatic-labelling-from-localhost/README.md +++ b/examples/automatic-labelling-from-localhost/README.md @@ -17,17 +17,23 @@ this directory: - `terraform apply` to apply the execution plan - `terraform destroy` to destroy the infrastructure -[^]: (autogen_docs_start) - + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| | project\_id | The ID of the project to which resources will be applied. | string | n/a | yes | | region | The region in which resources will be applied. | string | n/a | yes | +| subnetwork | The name or self_link of the subnetwork to create compute instance in. | string | `"default"` | no | | zone | The zone in which resources will be applied. | string | n/a | yes | -[^]: (autogen_docs_end) +## Outputs + +| Name | Description | +|------|-------------| +| compute\_instance\_name | The name of the unlabelled Compute instance. | + + ## Requirements @@ -42,7 +48,7 @@ must also be met. The following software dependencies must be installed on the system from which this module will be invoked: -- [Terraform][terraform-site] v0.11.Z +- [Terraform][terraform-site] v0.12 ### IAM Roles diff --git a/examples/automatic-labelling-from-localhost/main.tf b/examples/automatic-labelling-from-localhost/main.tf index 564149c..a00c9db 100644 --- a/examples/automatic-labelling-from-localhost/main.tf +++ b/examples/automatic-labelling-from-localhost/main.tf @@ -90,7 +90,7 @@ resource "google_compute_instance" "main" { } network_interface { - network = "default" + subnetwork = var.subnetwork } project = var.project_id diff --git a/examples/automatic-labelling-from-localhost/variables.tf b/examples/automatic-labelling-from-localhost/variables.tf index cbca8a0..25feac3 100644 --- a/examples/automatic-labelling-from-localhost/variables.tf +++ b/examples/automatic-labelling-from-localhost/variables.tf @@ -28,3 +28,9 @@ variable "zone" { type = string description = "The zone in which resources will be applied." } + +variable "subnetwork" { + type = string + description = "The name or self_link of the subnetwork to create compute instance in." + default = "default" +} diff --git a/examples/automatic-labelling-from-repository/README.md b/examples/automatic-labelling-from-repository/README.md index 12b84a3..4dd18a0 100644 --- a/examples/automatic-labelling-from-repository/README.md +++ b/examples/automatic-labelling-from-repository/README.md @@ -9,7 +9,7 @@ principal email address of the account responsible for causing the events. ## Usage -To provision this example, populate `terraform.tfvars` with the [required variables][#inputs] and run the following commands within +To provision this example, populate `terraform.tfvars` with the [required variables](#inputs) and run the following commands within this directory: - `terraform init` to initialize the directory @@ -17,17 +17,23 @@ this directory: - `terraform apply` to apply the execution plan - `terraform destroy` to destroy the infrastructure -[^]: (autogen_docs_start) - + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| | project\_id | The ID of the project to which resources will be applied. | string | n/a | yes | | region | The region in which resources will be applied. | string | n/a | yes | +| subnetwork | The name or self_link of the subnetwork to create compute instance in. | string | `"default"` | no | | zone | The zone in which resources will be applied. | string | n/a | yes | -[^]: (autogen_docs_end) +## Outputs + +| Name | Description | +|------|-------------| +| compute\_instance\_name | The name of the unlabelled Compute instance. | + + ## Requirements @@ -43,7 +49,7 @@ must also be met. The following software dependencies must be installed on the system from which this module will be invoked: -- [Terraform][terraform-site] v0.11.Z +- [Terraform][terraform-site] v0.12 ### IAM Roles @@ -65,3 +71,4 @@ following APIs enabled: [event-project-log-entry-submodule]: ../../modules/event-project-log-entry [repository-function-submodule-requirements]: ../../modules/repository-function/README.md#requirements [repository-function-submodule]: ../../modules/repository-function +[terraform-site]: https://terraform.io/ diff --git a/examples/automatic-labelling-from-repository/main.tf b/examples/automatic-labelling-from-repository/main.tf index e0e0fe0..59bcea2 100644 --- a/examples/automatic-labelling-from-repository/main.tf +++ b/examples/automatic-labelling-from-repository/main.tf @@ -119,7 +119,7 @@ resource "google_compute_instance" "main" { } network_interface { - network = "default" + subnetwork = var.subnetwork } project = var.project_id diff --git a/examples/automatic-labelling-from-repository/variables.tf b/examples/automatic-labelling-from-repository/variables.tf index cbca8a0..25feac3 100644 --- a/examples/automatic-labelling-from-repository/variables.tf +++ b/examples/automatic-labelling-from-repository/variables.tf @@ -28,3 +28,9 @@ variable "zone" { type = string description = "The zone in which resources will be applied." } + +variable "subnetwork" { + type = string + description = "The name or self_link of the subnetwork to create compute instance in." + default = "default" +} diff --git a/examples/delete-vms-without-cmek/README.md b/examples/delete-vms-without-cmek/README.md index a91d717..3c78b2e 100644 --- a/examples/delete-vms-without-cmek/README.md +++ b/examples/delete-vms-without-cmek/README.md @@ -16,8 +16,7 @@ this directory: - `terraform apply` to apply the execution plan - `terraform destroy` to destroy the infrastructure -[^]: (autogen_docs_start) - + ## Inputs | Name | Description | Type | Default | Required | @@ -25,7 +24,7 @@ this directory: | project\_id | The ID of the project to which resources will be applied. | string | n/a | yes | | region | The region in which resources will be applied. | string | n/a | yes | -[^]: (autogen_docs_end) + ## Requirements @@ -40,7 +39,7 @@ must also be met. The following software dependencies must be installed on the system from which this module will be invoked: -- [Terraform][terraform-site] v0.11.Z +- [Terraform][terraform-site] v0.12 ### IAM Roles diff --git a/helpers/terraform_docs b/helpers/terraform_docs deleted file mode 100755 index 0935b69..0000000 --- a/helpers/terraform_docs +++ /dev/null @@ -1,694 +0,0 @@ -#!/usr/bin/env bash - -set -e - -main() { - declare argv - argv=$(getopt -o a: --long args: -- "$@") || return - eval "set -- $argv" - - declare args - declare files - - for argv; do - case $argv in - (-a|--args) - shift - args="$1" - shift - ;; - (--) - shift - files="$@" - break - ;; - esac - done - - local hack_terraform_docs=$(terraform version | head -1 | grep -c 0.12) - - if [[ "$hack_terraform_docs" == "1" ]]; then - which awk 2>&1 >/dev/null || ( echo "awk is required for terraform-docs hack to work with Terraform 0.12"; exit 1) - - tmp_file_awk=$(mktemp "${TMPDIR:-/tmp}/terraform-docs-XXXXXXXXXX") - terraform_docs_awk "$tmp_file_awk" - terraform_docs "$tmp_file_awk" "$args" "$files" - rm -f "$tmp_file_awk" - else - terraform_docs "0" "$args" "$files" - fi - -} - -terraform_docs() { - readonly terraform_docs_awk_file="$1" - readonly args="$2" - readonly files="$3" - - declare -a paths - declare -a tfvars_files - - index=0 - - for file_with_path in $files; do - file_with_path="${file_with_path// /__REPLACED__SPACE__}" - - paths[index]=$(dirname "$file_with_path") - - if [[ "$file_with_path" == *".tfvars" ]]; then - tfvars_files+=("$file_with_path") - fi - - ((index+=1)) - done - - readonly tmp_file=$(mktemp) - readonly text_file="README.md" - - for path_uniq in $(echo "${paths[*]}" | tr ' ' '\n' | sort -u); do - path_uniq="${path_uniq//__REPLACED__SPACE__/ }" - - pushd "$path_uniq" > /dev/null - - if [[ ! -f "$text_file" ]]; then - popd > /dev/null - continue - fi - - if [[ "$terraform_docs_awk_file" == "0" ]]; then - terraform-docs $args md ./ > "$tmp_file" - else - # Can't append extension for mktemp, so renaming instead - tmp_file_docs=$(mktemp "${TMPDIR:-/tmp}/terraform-docs-XXXXXXXXXX") - mv "$tmp_file_docs" "$tmp_file_docs.tf" - tmp_file_docs_tf="$tmp_file_docs.tf" - - awk -f "$terraform_docs_awk_file" ./*.tf > "$tmp_file_docs_tf" - terraform-docs $args md "$tmp_file_docs_tf" > "$tmp_file" - rm -f "$tmp_file_docs_tf" - fi - - # Replace content between markers with the placeholder - https://stackoverflow.com/questions/1212799/how-do-i-extract-lines-between-two-line-delimiters-in-perl#1212834 - perl -i -ne 'if (/BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/../END OF PRE-COMMIT-TERRAFORM DOCS HOOK/) { print $_ if /BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/; print "I_WANT_TO_BE_REPLACED\n$_" if /END OF PRE-COMMIT-TERRAFORM DOCS HOOK/;} else { print $_ }' "$text_file" - - # Replace placeholder with the content of the file - perl -i -e 'open(F, "'"$tmp_file"'"); $f = join "", ; while(<>){if (/I_WANT_TO_BE_REPLACED/) {print $f} else {print $_};}' "$text_file" - - rm -f "$tmp_file" - - popd > /dev/null - done -} - -terraform_docs_awk() { - readonly output_file=$1 - - cat <<"EOF" > $output_file -# 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 - -# Script was originally found here: https://github.com/cloudposse/build-harness/blob/master/bin/terraform-docs.awk - -{ - if ( $0 ~ /\{/ ) { - braceCnt++ - } - - if ( $0 ~ /\}/ ) { - braceCnt-- - } - - # [START] variable or output block started - if ($0 ~ /^[[:space:]]*(variable|output)[[:space:]][[:space:]]*"(.*?)"/) { - # Normalize the braceCnt (should be 1 now) - braceCnt = 1 - # [CLOSE] "default" block - if (blockDefCnt > 0) { - blockDefCnt = 0 - } - blockCnt++ - print $0 - } - - # [START] multiline default statement started - if (blockCnt > 0) { - if ($0 ~ /^[[:space:]][[:space:]]*(default)[[:space:]][[:space:]]*=/) { - if ($3 ~ "null") { - print " default = \"null\"" - } else { - print $0 - blockDefCnt++ - blockDefStart=1 - } - } - } - - # [PRINT] single line "description" - if (blockCnt > 0) { - if (blockDefCnt == 0) { - if ($0 ~ /^[[:space:]][[:space:]]*description[[:space:]][[:space:]]*=/) { - # [CLOSE] "default" block - if (blockDefCnt > 0) { - blockDefCnt = 0 - } - print $0 - } - } - } - - # [PRINT] single line "type" - if (blockCnt > 0) { - if ($0 ~ /^[[:space:]][[:space:]]*type[[:space:]][[:space:]]*=/ ) { - # [CLOSE] "default" block - if (blockDefCnt > 0) { - blockDefCnt = 0 - } - type=$3 - if (type ~ "object") { - print " type = \"object\"" - } else { - # legacy quoted types: "string", "list", and "map" - if ($3 ~ /^[[:space:]]*"(.*?)"[[:space:]]*$/) { - print " type = " $3 - } else { - print " type = \"" $3 "\"" - } - } - } - } - - # [CLOSE] variable/output block - if (blockCnt > 0) { - if (braceCnt == 0 && blockCnt > 0) { - blockCnt-- - print $0 - } - } - - # [PRINT] Multiline "default" statement - if (blockCnt > 0 && blockDefCnt > 0) { - if (blockDefStart == 1) { - blockDefStart = 0 - } else { - print $0 - } - } -} -EOF - -} - -getopt() { - # pure-getopt, a drop-in replacement for GNU getopt in pure Bash. - # version 1.4.3 - # - # Copyright 2012-2018 Aron Griffis - # - # Permission is hereby granted, free of charge, to any person obtaining - # a copy of this software and associated documentation files (the - # "Software"), to deal in the Software without restriction, including - # without limitation the rights to use, copy, modify, merge, publish, - # distribute, sublicense, and/or sell copies of the Software, and to - # permit persons to whom the Software is furnished to do so, subject to - # the following conditions: - # - # The above copyright notice and this permission notice shall be included - # in all copies or substantial portions of the Software. - # - # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - _getopt_main() { - # Returns one of the following statuses: - # 0 success - # 1 error parsing parameters - # 2 error in getopt invocation - # 3 internal error - # 4 reserved for -T - # - # For statuses 0 and 1, generates normalized and shell-quoted - # "options -- parameters" on stdout. - - declare parsed status - declare short long name flags - declare have_short=false - - # Synopsis from getopt man-page: - # - # getopt optstring parameters - # getopt [options] [--] optstring parameters - # getopt [options] -o|--options optstring [options] [--] parameters - # - # The first form can be normalized to the third form which - # _getopt_parse() understands. The second form can be recognized after - # first parse when $short hasn't been set. - - if [[ -n ${GETOPT_COMPATIBLE+isset} || $1 == [^-]* ]]; then - # Enable compatibility mode - flags=c$flags - # Normalize first to third synopsis form - set -- -o "$1" -- "${@:2}" - fi - - # First parse always uses flags=p since getopt always parses its own - # arguments effectively in this mode. - parsed=$(_getopt_parse getopt ahl:n:o:qQs:TuV \ - alternative,help,longoptions:,name:,options:,quiet,quiet-output,shell:,test,version \ - p "$@") - status=$? - if [[ $status != 0 ]]; then - if [[ $status == 1 ]]; then - echo "Try \`getopt --help' for more information." >&2 - # Since this is the first parse, convert status 1 to 2 - status=2 - fi - return $status - fi - eval "set -- $parsed" - - while [[ $# -gt 0 ]]; do - case $1 in - (-a|--alternative) - flags=a$flags ;; - - (-h|--help) - _getopt_help - return 2 # as does GNU getopt - ;; - - (-l|--longoptions) - long="$long${long:+,}$2" - shift ;; - - (-n|--name) - name=$2 - shift ;; - - (-o|--options) - short=$2 - have_short=true - shift ;; - - (-q|--quiet) - flags=q$flags ;; - - (-Q|--quiet-output) - flags=Q$flags ;; - - (-s|--shell) - case $2 in - (sh|bash) - flags=${flags//t/} ;; - (csh|tcsh) - flags=t$flags ;; - (*) - echo 'getopt: unknown shell after -s or --shell argument' >&2 - echo "Try \`getopt --help' for more information." >&2 - return 2 ;; - esac - shift ;; - - (-u|--unquoted) - flags=u$flags ;; - - (-T|--test) - return 4 ;; - - (-V|--version) - echo "pure-getopt 1.4.3" - return 0 ;; - - (--) - shift - break ;; - esac - - shift - done - - if ! $have_short; then - # $short was declared but never set, not even to an empty string. - # This implies the second form in the synopsis. - if [[ $# == 0 ]]; then - echo 'getopt: missing optstring argument' >&2 - echo "Try \`getopt --help' for more information." >&2 - return 2 - fi - short=$1 - have_short=true - shift - fi - - if [[ $short == -* ]]; then - # Leading dash means generate output in place rather than reordering, - # unless we're already in compatibility mode. - [[ $flags == *c* ]] || flags=i$flags - short=${short#?} - elif [[ $short == +* ]]; then - # Leading plus means POSIXLY_CORRECT, unless we're already in - # compatibility mode. - [[ $flags == *c* ]] || flags=p$flags - short=${short#?} - fi - - # This should fire if POSIXLY_CORRECT is in the environment, even if - # it's an empty string. That's the difference between :+ and + - flags=${POSIXLY_CORRECT+p}$flags - - _getopt_parse "${name:-getopt}" "$short" "$long" "$flags" "$@" - } - - _getopt_parse() { - # Inner getopt parser, used for both first parse and second parse. - # Returns 0 for success, 1 for error parsing, 3 for internal error. - # In the case of status 1, still generates stdout with whatever could - # be parsed. - # - # $flags is a string of characters with the following meanings: - # a - alternative parsing mode - # c - GETOPT_COMPATIBLE - # i - generate output in place rather than reordering - # p - POSIXLY_CORRECT - # q - disable error reporting - # Q - disable normal output - # t - quote for csh/tcsh - # u - unquoted output - - declare name="$1" short="$2" long="$3" flags="$4" - shift 4 - - # Split $long on commas, prepend double-dashes, strip colons; - # for use with _getopt_resolve_abbrev - declare -a longarr - _getopt_split longarr "$long" - longarr=( "${longarr[@]/#/--}" ) - longarr=( "${longarr[@]%:}" ) - longarr=( "${longarr[@]%:}" ) - - # Parse and collect options and parameters - declare -a opts params - declare o alt_recycled=false error=0 - - while [[ $# -gt 0 ]]; do - case $1 in - (--) - params=( "${params[@]}" "${@:2}" ) - break ;; - - (--*=*) - o=${1%%=*} - if ! o=$(_getopt_resolve_abbrev "$o" "${longarr[@]}"); then - error=1 - elif [[ ,"$long", == *,"${o#--}"::,* ]]; then - opts=( "${opts[@]}" "$o" "${1#*=}" ) - elif [[ ,"$long", == *,"${o#--}":,* ]]; then - opts=( "${opts[@]}" "$o" "${1#*=}" ) - elif [[ ,"$long", == *,"${o#--}",* ]]; then - if $alt_recycled; then o=${o#-}; fi - _getopt_err "$name: option '$o' doesn't allow an argument" - error=1 - else - echo "getopt: assertion failed (1)" >&2 - return 3 - fi - alt_recycled=false - ;; - - (--?*) - o=$1 - if ! o=$(_getopt_resolve_abbrev "$o" "${longarr[@]}"); then - error=1 - elif [[ ,"$long", == *,"${o#--}",* ]]; then - opts=( "${opts[@]}" "$o" ) - elif [[ ,"$long", == *,"${o#--}::",* ]]; then - opts=( "${opts[@]}" "$o" '' ) - elif [[ ,"$long", == *,"${o#--}:",* ]]; then - if [[ $# -ge 2 ]]; then - shift - opts=( "${opts[@]}" "$o" "$1" ) - else - if $alt_recycled; then o=${o#-}; fi - _getopt_err "$name: option '$o' requires an argument" - error=1 - fi - else - echo "getopt: assertion failed (2)" >&2 - return 3 - fi - alt_recycled=false - ;; - - (-*) - if [[ $flags == *a* ]]; then - # Alternative parsing mode! - # Try to handle as a long option if any of the following apply: - # 1. There's an equals sign in the mix -x=3 or -xy=3 - # 2. There's 2+ letters and an abbreviated long match -xy - # 3. There's a single letter and an exact long match - # 4. There's a single letter and no short match - o=${1::2} # temp for testing #4 - if [[ $1 == *=* || $1 == -?? || \ - ,$long, == *,"${1#-}"[:,]* || \ - ,$short, != *,"${o#-}"[:,]* ]]; then - o=$(_getopt_resolve_abbrev "${1%%=*}" "${longarr[@]}" 2>/dev/null) - case $? in - (0) - # Unambiguous match. Let the long options parser handle - # it, with a flag to get the right error message. - set -- "-$1" "${@:2}" - alt_recycled=true - continue ;; - (1) - # Ambiguous match, generate error and continue. - _getopt_resolve_abbrev "${1%%=*}" "${longarr[@]}" >/dev/null - error=1 - shift - continue ;; - (2) - # No match, fall through to single-character check. - true ;; - (*) - echo "getopt: assertion failed (3)" >&2 - return 3 ;; - esac - fi - fi - - o=${1::2} - if [[ "$short" == *"${o#-}"::* ]]; then - if [[ ${#1} -gt 2 ]]; then - opts=( "${opts[@]}" "$o" "${1:2}" ) - else - opts=( "${opts[@]}" "$o" '' ) - fi - elif [[ "$short" == *"${o#-}":* ]]; then - if [[ ${#1} -gt 2 ]]; then - opts=( "${opts[@]}" "$o" "${1:2}" ) - elif [[ $# -ge 2 ]]; then - shift - opts=( "${opts[@]}" "$o" "$1" ) - else - _getopt_err "$name: option requires an argument -- '${o#-}'" - error=1 - fi - elif [[ "$short" == *"${o#-}"* ]]; then - opts=( "${opts[@]}" "$o" ) - if [[ ${#1} -gt 2 ]]; then - set -- "$o" "-${1:2}" "${@:2}" - fi - else - if [[ $flags == *a* ]]; then - # Alternative parsing mode! Report on the entire failed - # option. GNU includes =value but we omit it for sanity with - # very long values. - _getopt_err "$name: unrecognized option '${1%%=*}'" - else - _getopt_err "$name: invalid option -- '${o#-}'" - if [[ ${#1} -gt 2 ]]; then - set -- "$o" "-${1:2}" "${@:2}" - fi - fi - error=1 - fi ;; - - (*) - # GNU getopt in-place mode (leading dash on short options) - # overrides POSIXLY_CORRECT - if [[ $flags == *i* ]]; then - opts=( "${opts[@]}" "$1" ) - elif [[ $flags == *p* ]]; then - params=( "${params[@]}" "$@" ) - break - else - params=( "${params[@]}" "$1" ) - fi - esac - - shift - done - - if [[ $flags == *Q* ]]; then - true # generate no output - else - echo -n ' ' - if [[ $flags == *[cu]* ]]; then - printf '%s -- %s' "${opts[*]}" "${params[*]}" - else - if [[ $flags == *t* ]]; then - _getopt_quote_csh "${opts[@]}" -- "${params[@]}" - else - _getopt_quote "${opts[@]}" -- "${params[@]}" - fi - fi - echo - fi - - return $error - } - - _getopt_err() { - if [[ $flags != *q* ]]; then - printf '%s\n' "$1" >&2 - fi - } - - _getopt_resolve_abbrev() { - # Resolves an abbrevation from a list of possibilities. - # If the abbreviation is unambiguous, echoes the expansion on stdout - # and returns 0. If the abbreviation is ambiguous, prints a message on - # stderr and returns 1. (For first parse this should convert to exit - # status 2.) If there is no match at all, prints a message on stderr - # and returns 2. - declare a q="$1" - declare -a matches - shift - for a; do - if [[ $q == "$a" ]]; then - # Exact match. Squash any other partial matches. - matches=( "$a" ) - break - elif [[ $flags == *a* && $q == -[^-]* && $a == -"$q" ]]; then - # Exact alternative match. Squash any other partial matches. - matches=( "$a" ) - break - elif [[ $a == "$q"* ]]; then - # Abbreviated match. - matches=( "${matches[@]}" "$a" ) - elif [[ $flags == *a* && $q == -[^-]* && $a == -"$q"* ]]; then - # Abbreviated alternative match. - matches=( "${matches[@]}" "${a#-}" ) - fi - done - case ${#matches[@]} in - (0) - [[ $flags == *q* ]] || \ - printf "$name: unrecognized option %s\\n" >&2 \ - "$(_getopt_quote "$q")" - return 2 ;; - (1) - printf '%s' "${matches[0]}"; return 0 ;; - (*) - [[ $flags == *q* ]] || \ - printf "$name: option %s is ambiguous; possibilities: %s\\n" >&2 \ - "$(_getopt_quote "$q")" "$(_getopt_quote "${matches[@]}")" - return 1 ;; - esac - } - - _getopt_split() { - # Splits $2 at commas to build array specified by $1 - declare IFS=, - eval "$1=( \$2 )" - } - - _getopt_quote() { - # Quotes arguments with single quotes, escaping inner single quotes - declare s space q=\' - for s; do - printf "$space'%s'" "${s//$q/$q\\$q$q}" - space=' ' - done - } - - _getopt_quote_csh() { - # Quotes arguments with single quotes, escaping inner single quotes, - # bangs, backslashes and newlines - declare s i c space - for s; do - echo -n "$space'" - for ((i=0; i<${#s}; i++)); do - c=${s:i:1} - case $c in - (\\|\'|!) - echo -n "'\\$c'" ;; - ($'\n') - echo -n "\\$c" ;; - (*) - echo -n "$c" ;; - esac - done - echo -n \' - space=' ' - done - } - - _getopt_help() { - cat <<-EOT >&2 - - Usage: - getopt - getopt [options] [--] - getopt [options] -o|--options [options] [--] - - Parse command options. - - Options: - -a, --alternative allow long options starting with single - - -l, --longoptions the long options to be recognized - -n, --name the name under which errors are reported - -o, --options the short options to be recognized - -q, --quiet disable error reporting by getopt(3) - -Q, --quiet-output no normal output - -s, --shell set quoting conventions to those of - -T, --test test for getopt(1) version - -u, --unquoted do not quote the output - - -h, --help display this help and exit - -V, --version output version information and exit - - For more details see getopt(1). - EOT - } - - _getopt_version_check() { - if [[ -z $BASH_VERSION ]]; then - echo "getopt: unknown version of bash might not be compatible" >&2 - return 1 - fi - - # This is a lexical comparison that should be sufficient forever. - if [[ $BASH_VERSION < 2.05b ]]; then - echo "getopt: bash $BASH_VERSION might not be compatible" >&2 - return 1 - fi - - return 0 - } - - _getopt_version_check - _getopt_main "$@" - declare status=$? - unset -f _getopt_main _getopt_err _getopt_parse _getopt_quote \ - _getopt_quote_csh _getopt_resolve_abbrev _getopt_split _getopt_help \ - _getopt_version_check - return $status -} - -[[ $BASH_SOURCE != "$0" ]] || main "$@" diff --git a/helpers/terraform_validate b/helpers/terraform_validate deleted file mode 100755 index 7f60982..0000000 --- a/helpers/terraform_validate +++ /dev/null @@ -1,23 +0,0 @@ -#! /bin/bash -# -# Copyright 2019 Google LLC. This software is provided as-is, without warranty -# or representation for any use or purpose. Your use of it is subject to your -# agreement with Google. -# -# This script initializes modules so that terraform validate as of 0.12 behaves -# as expected and does not issue errors such as: -# -# Error: Module not installed -# -# on test/fixtures/shared_vpc_no_subnets/main.tf line 37: -# 37: module "project-factory" { -# -# This module is not yet installed. Run "terraform init" to install all modules -# required by this configuration. - -# The first and only argument to this script is the directory containing *.tf -# files to validate. This directory is assumed to be a root module. - -cd "$1" -terraform init -backend=false -terraform validate diff --git a/modules/event-folder-log-entry/README.md b/modules/event-folder-log-entry/README.md index 9e0d7cf..aa0a62f 100644 --- a/modules/event-folder-log-entry/README.md +++ b/modules/event-folder-log-entry/README.md @@ -13,9 +13,8 @@ export event. ## Usage The -[automatic-labelling-from-localhost example][a7c-l7g-from-l7t-example] -is a tested reference of how to use this submodule with the -[root module]. +[automatic-labelling-from-localhost example][automatic-labelling-from-localhost] is a tested reference of how to use this submodule with the +[root module][root-module]. ## Inputs @@ -46,9 +45,8 @@ order to invoke this module. The following software dependencies must be installed on the system from which this module will be invoked: -- [Terraform][terraform-site] v0.11.Z -- [Terraform Provider for Google Cloud Platform][t7m-provider-gcp-site] - v2.1.Z +- [Terraform][terraform-site] v0.12 +- [Terraform Provider for Google Cloud Platform][terraform-provider-gcp-site] v2.5 ### IAM Roles @@ -67,7 +65,8 @@ following APIs enabled: - Cloud Pub/Sub API: `pubsub.googleapis.com` - Stackdriver Logging API: `logging.googleapis.com` -[automatic-labelling-example]: ../../examples/automatic_labelling +[automatic-labelling-from-localhost]: ../../examples/automatic-labelling-from-localhost [repository-function]: ../repository-function [root-module]: ../.. [terraform-site]: https://www.terraform.io/ +[terraform-provider-gcp-site]: https://github.com/terraform-providers/terraform-provider-google diff --git a/modules/event-project-log-entry/README.md b/modules/event-project-log-entry/README.md index 7840584..3beabba 100644 --- a/modules/event-project-log-entry/README.md +++ b/modules/event-project-log-entry/README.md @@ -13,19 +13,18 @@ export event. ## Usage The -[automatic-labelling-from-localhost example][a7c-l7g-from-l7t-example] -is a tested reference of how to use this submodule with the -[root module]. - -[^]: (autogen_docs_start) +[automatic-labelling-from-localhost example][automatic-labelling-from-localhost] is a tested reference of how to use this submodule with the +[root module][root-module]. + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| | filter | The filter to apply when exporting logs. | string | n/a | yes | -| labels | A set of key/value label pairs to assign to any labelable resources. | map | `` | no | +| labels | A set of key/value label pairs to assign to any labelable resources. | map(string) | `` | no | | name | The name to apply to any nameable resources. | string | n/a | yes | +| parent\_resource\_type | The GCP resource in which you create the log sink. The value must not be computed, and must be one of the following: 'project', 'folder', 'billing_account', or 'organization'. | string | `"project"` | no | | project\_id | The ID of the project to which resources will be applied. | string | n/a | yes | ## Outputs @@ -34,7 +33,7 @@ is a tested reference of how to use this submodule with the |------|-------------| | function\_event\_trigger | The information used to trigger the function when a log entry is exported to the topic. | -[^]: (autogen_docs_end) + ## Requirements @@ -46,9 +45,8 @@ order to invoke this module. The following software dependencies must be installed on the system from which this module will be invoked: -- [Terraform][terraform-site] v0.11.Z -- [Terraform Provider for Google Cloud Platform][t7m-provider-gcp-site] - v2.1.Z +- [Terraform][terraform-site] v0.12 +- [Terraform Provider for Google Cloud Platform][terraform-provider-gcp-site] v2.5 ### IAM Roles @@ -67,7 +65,8 @@ following APIs enabled: - Cloud Pub/Sub API: `pubsub.googleapis.com` - Stackdriver Logging API: `logging.googleapis.com` -[automatic-labelling-example]: ../../examples/automatic_labelling +[automatic-labelling-from-localhost]: ../../examples/automatic-labelling-from-localhost [repository-function]: ../repository-function [root-module]: ../.. [terraform-site]: https://www.terraform.io/ +[terraform-provider-gcp-site]: https://github.com/terraform-providers/terraform-provider-google diff --git a/modules/repository-function/README.md b/modules/repository-function/README.md index 538491f..600faf7 100644 --- a/modules/repository-function/README.md +++ b/modules/repository-function/README.md @@ -13,24 +13,23 @@ The is a tested reference of how to use this submodule with the [event-project-log-entry submodule][event-project-log-entry-submodule]. -[^]: (autogen_docs_start) - + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| available\_memory\_mb | The amount of memory in megabytes allotted for the function to use. | string | `"256"` | no | +| available\_memory\_mb | The amount of memory in megabytes allotted for the function to use. | number | `"256"` | no | | description | The description of the function. | string | `"Processes events."` | no | | entry\_point | The name of a method in the function source which will be invoked when the function is executed. | string | n/a | yes | -| environment\_variables | A set of key/value environment variable pairs to assign to the function. | map | `` | no | -| event\_trigger | A source that fires events in response to a condition in another service. | map | n/a | yes | -| labels | A set of key/value label pairs to assign to any lableable resources. | map | `` | no | +| environment\_variables | A set of key/value environment variable pairs to assign to the function. | map(string) | `` | no | +| event\_trigger | A source that fires events in response to a condition in another service. | map(string) | n/a | yes | +| labels | A set of key/value label pairs to assign to any lableable resources. | map(string) | `` | no | | name | The name to apply to any nameable resources. | string | n/a | yes | | project\_id | The ID of the project to which resources will be applied. | string | n/a | yes | | region | The region in which resources will be applied. | string | n/a | yes | | runtime | The runtime in which the function will be executed. | string | `"nodejs6"` | no | | source\_repository\_url | The URL of the repository which contains the function source code. | string | n/a | yes | -| timeout\_s | The amount of time in seconds allotted for the execution of the function. | string | `"60"` | no | +| timeout\_s | The amount of time in seconds allotted for the execution of the function. | number | `"60"` | no | ## Outputs @@ -38,7 +37,7 @@ is a tested reference of how to use this submodule with the |------|-------------| | name | The name of the function. | -[^]: (autogen_docs_end) + ## Requirements @@ -50,9 +49,8 @@ order to invoke this module. The following software dependencies must be installed on the system from which this module will be invoked: -- [Terraform][terraform-site] v0.11.Z -- [Terraform Provider for Google Cloud Platform][t7m-provider-gcp-site] - v2.1.Z +- [Terraform][terraform-site] v0.12 +- [Terraform Provider for Google Cloud Platform][terraform-provider-gcp-site] v2.5 ### IAM Roles @@ -68,6 +66,8 @@ following APIs enabled: - Cloud Functions API: `cloudfunctions.googleapis.com` +[root-module]: ../.. [automatic-labelling-from-repository-example]: ../../examples/automatic-labelling-from-repository [event-project-log-entry-submodule]: ../event-project-log-entry [terraform-site]: https://www.terraform.io/ +[terraform-provider-gcp-site]: https://github.com/terraform-providers/terraform-provider-google diff --git a/test/fixtures/automatic-labelling-from-localhost/main.tf b/test/fixtures/automatic-labelling-from-localhost/main.tf index 65602a6..fa2b085 100644 --- a/test/fixtures/automatic-labelling-from-localhost/main.tf +++ b/test/fixtures/automatic-labelling-from-localhost/main.tf @@ -19,5 +19,6 @@ module "automatic_labelling_from_localhost" { project_id = var.project_id region = var.region + subnetwork = var.subnetwork zone = var.zone } diff --git a/test/fixtures/automatic-labelling-from-localhost/variables.tf b/test/fixtures/automatic-labelling-from-localhost/variables.tf index cbca8a0..70284ac 100644 --- a/test/fixtures/automatic-labelling-from-localhost/variables.tf +++ b/test/fixtures/automatic-labelling-from-localhost/variables.tf @@ -28,3 +28,8 @@ variable "zone" { type = string description = "The zone in which resources will be applied." } + +variable "subnetwork" { + type = string + description = "The name or self_link of the subnetwork to create compute instance in." +} diff --git a/test/fixtures/automatic-labelling-from-repository/main.tf b/test/fixtures/automatic-labelling-from-repository/main.tf index 3a491c9..80e30ff 100644 --- a/test/fixtures/automatic-labelling-from-repository/main.tf +++ b/test/fixtures/automatic-labelling-from-repository/main.tf @@ -19,5 +19,6 @@ module "automatic_labelling_from_repository" { project_id = var.project_id region = var.region + subnetwork = var.subnetwork zone = var.zone } diff --git a/test/fixtures/automatic-labelling-from-repository/variables.tf b/test/fixtures/automatic-labelling-from-repository/variables.tf index cbca8a0..70284ac 100644 --- a/test/fixtures/automatic-labelling-from-repository/variables.tf +++ b/test/fixtures/automatic-labelling-from-repository/variables.tf @@ -28,3 +28,8 @@ variable "zone" { type = string description = "The zone in which resources will be applied." } + +variable "subnetwork" { + type = string + description = "The name or self_link of the subnetwork to create compute instance in." +} diff --git a/test/integration/automatic-labelling-instances/controls/automatically_labelled.rb b/test/integration/automatic-labelling-instances/controls/automatically_labelled.rb index 399569c..2883061 100644 --- a/test/integration/automatic-labelling-instances/controls/automatically_labelled.rb +++ b/test/integration/automatic-labelling-instances/controls/automatically_labelled.rb @@ -1,10 +1,10 @@ -# Copyright 2019 Google Inc. +# Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. - # frozen_string_literal: true require "json" diff --git a/test/integration/automatic-labelling-projects/controls/automatically_labelled.rb b/test/integration/automatic-labelling-projects/controls/automatically_labelled.rb index 79b4db9..1a15665 100644 --- a/test/integration/automatic-labelling-projects/controls/automatically_labelled.rb +++ b/test/integration/automatic-labelling-projects/controls/automatically_labelled.rb @@ -1,10 +1,10 @@ -# Copyright 2019 Google Inc. +# Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/test/setup/main.tf b/test/setup/main.tf index a29e733..e6b3176 100644 --- a/test/setup/main.tf +++ b/test/setup/main.tf @@ -32,12 +32,11 @@ module "project" { source = "terraform-google-modules/project-factory/google" version = "~> 3.0" - name = local.project_name - random_project_id = true - auto_create_network = true - org_id = var.org_id - folder_id = var.folder_id - billing_account = var.billing_account + name = local.project_name + random_project_id = true + org_id = var.org_id + folder_id = var.folder_id + billing_account = var.billing_account activate_apis = [ "cloudresourcemanager.googleapis.com", @@ -50,3 +49,16 @@ module "project" { ] } +module "network" { + source = "terraform-google-modules/network/google" + version = "~> 1.2" + + project_id = module.project.project_id + network_name = "test-network" + + subnets = [{ + subnet_name = "test-subnet-01" + subnet_ip = "10.10.10.0/24" + subnet_region = var.region + }] +} diff --git a/test/setup/make_source.sh b/test/setup/make_source.sh index 53a98af..b104da4 100755 --- a/test/setup/make_source.sh +++ b/test/setup/make_source.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright 2018 Google LLC +# Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ project_id=$(terraform output project_id) region=$(terraform output region) zone=$(terraform output zone) sub_folder_id=$(terraform output sub_folder_id) +subnetwork=$(terraform output subnetwork) { echo "#!/usr/bin/env bash" @@ -25,10 +26,9 @@ sub_folder_id=$(terraform output sub_folder_id) echo "export TF_VAR_region='$region'" echo "export TF_VAR_zone='$zone'" echo "export TF_VAR_folder_id='$sub_folder_id'" + echo "export TF_VAR_subnetwork='$subnetwork'" } > ../source.sh sa_json=$(terraform output sa_key) # shellcheck disable=SC2086 echo "export SERVICE_ACCOUNT_JSON='$(echo $sa_json | base64 --decode)'" >> ../source.sh - - diff --git a/test/setup/outputs.tf b/test/setup/outputs.tf index 1384ba4..25a9acb 100644 --- a/test/setup/outputs.tf +++ b/test/setup/outputs.tf @@ -35,3 +35,7 @@ output "zone" { value = var.zone } +output "subnetwork" { + value = module.network.subnets_self_links[0] +} +